Claude Code가 API Error: 400 due to tool use concurrency issues를 보여 주면, 첫 판단을 quota 부족, API key 문제, Anthropic 장애, provider 문제로 두지 마세요. 이 exact error에서는 먼저 현재 대화나 API 요청 안의 도구 기록이 깨졌는지 봐야 합니다. Claude Code 사용자는 현재 작업 상태와 오류 문구를 저장한 뒤 /rewind 또는 Esc 두 번으로 손상된 tool turn 이전으로 돌아가야 합니다. Anthropic Messages API를 직접 다루는 개발자는 직전 assistant의 tool_use마다 다음 user message 안에 대응하는 tool_result가 있는지, 그리고 결과 블록이 일반 텍스트보다 앞에 있는지 확인해야 합니다.
| 사용 환경 | 먼저 확인할 소유자 | 첫 안전 조치 |
|---|---|---|
| Claude Code CLI | 도구 또는 thinking 기록 불일치 | 컨텍스트를 저장하고 /rewind 또는 Esc 두 번 후 작은 도구 동작으로 검증 |
| VS Code, Cursor, IDE 확장 | 확장 또는 클라이언트가 저장한 히스토리 | 같은 작은 도구 동작을 CLI와 IDE에서 비교하고 바로 재설치하지 않기 |
| 직접 만든 Anthropic API 클라이언트 | tool_result 직렬화 오류 | 모든 tool_use_id에 결과를 대응시키고 한 user message에 모아 텍스트보다 앞에 두기 |
| 다른 400 문구 | schema, role, system, extra input 검증 | 실제 validation error에 맞춰 수정 |
| 429, 529, 500, connection, auth, billing | 다른 Claude 오류 계열 | rate, overload, server, network, account 분기로 이동 |
이 단계에서 key를 교체하거나 quota를 구매하거나 provider를 바꾸거나 전체 장애라고 단정하면 문제를 놓치기 쉽습니다. Claude Code에서는 rewind 후 파일 하나 읽기, 디렉터리 하나 보기, 짧은 명령 하나 실행하기처럼 지루한 검증을 합니다. API 클라이언트에서는 민감정보를 뺀 message shape를 출력해 role, block type, tool ID, 결과 개수, 순서를 확인합니다.
이 400이 실제로 가리키는 것
“tool use concurrency issues”라는 표현은 동시에 너무 많은 도구를 실행했다는 뜻처럼 보입니다. 하지만 이 오류에서 더 중요한 질문은 실행 개수가 아니라 “다음 요청에 실린 대화 상태가 API가 이어 갈 수 있는 형태인가”입니다. Claude Code 문서는 이 오류를 tool use 또는 thinking block mismatch와 연결하고, Claude API의 HTTP 400은 요청 형식이나 내용이 잘못된 invalid_request_error 범주입니다.
즉 모델이 작업 자체를 거절한 것이 아니라, 다음 요청의 도구 기록을 해석할 수 없다는 뜻입니다. Claude Code에서는 긴 세션, 중단된 도구 실행, 끊긴 스트림, IDE 확장의 오래된 상태, 사용자가 편집한 히스토리, 압축된 메시지가 원인이 될 수 있습니다. 직접 만든 클라이언트에서는 tool_result 누락, 여러 user message로 나뉜 결과, 결과 앞에 삽입된 텍스트, 잘못된 tool_use_id가 흔한 원인입니다.
그래서 일반 채팅은 응답하지만 파일 읽기나 편집만 실패할 수 있습니다. 텍스트 대화는 도구 결과의 짝을 필요로 하지 않습니다. 하지만 Read, Edit, Bash, Search 같은 도구 동작은 ID, 순서, role, content block type이 모두 맞아야 합니다. 이 차이를 무시하면 네트워크나 결제 문제만 오래 보게 됩니다.
Claude Code 세션을 먼저 복구하세요

첫 단계는 전체 transcript를 보존하는 것이 아니라 사람이 다시 사용할 수 있는 작업 상태를 남기는 것입니다. 현재 목표, 수정 중인 파일, 직전에 실행한 도구, 정확한 오류 문구, 시간대가 포함된 시각, CLI인지 IDE인지, 일반 채팅이 가능한지를 기록합니다. 이 정보는 새 세션이 필요해져도 안전하게 옮길 수 있습니다.
다음으로 사용 환경을 분리합니다. CLI에서 오류가 났다면 Claude Code 버전을 확인하고 너무 오래된 경우 업데이트를 고려합니다. VS Code나 Cursor에서만 보였다면 같은 작은 도구 동작을 CLI에서 시도합니다. CLI가 정상이고 IDE만 실패한다면 긴급한 작업은 CLI에서 이어 가고, IDE 확장 버전과 최소 재현 동작을 별도로 기록합니다.
세션 자체가 깨졌다고 보이면 /rewind를 사용합니다. Claude Code에서는 Esc를 두 번 눌러 이전 대화 상태로 돌아가는 방법도 사용할 수 있습니다. 돌아온 직후에는 큰 복합 지시를 하지 마세요. 여러 파일 수정, 테스트 실행, 문서 검색을 한꺼번에 요청하지 말고 파일 하나 읽기 같은 작은 동작으로 복구 여부를 확인합니다.
그 작은 동작도 같은 exact error를 내면 새 세션을 검토합니다. 새 세션에는 작업 요약, 관련 파일, 마지막으로 신뢰할 수 있는 상태, 민감정보를 뺀 오류 증거만 가져갑니다. 손상된 도구 히스토리 전체를 붙여 넣으면 새 대화에서도 같은 400을 다시 만들 수 있습니다.
IDE, Cursor, VS Code에서는 표면을 나눠 보세요
IDE 통합에서 이 오류가 나면 “일반 대화는 되는데 도구만 실패”하는 모양이 자주 보입니다. 이것은 사용자가 실제로 여러 도구를 동시에 실행했다는 증거가 아닙니다. IDE 확장이 부분 상태를 저장했거나, CLI와 에디터 사이의 bridge가 오래된 메시지를 재전송했거나, remote environment 버전이 다르거나, 확장 쪽만 손상된 tool turn을 들고 있을 수 있습니다.
순서는 단순합니다. 먼저 표면을 기록합니다. Claude Code CLI, VS Code, Cursor, remote SSH, WSL, terminal multiplexer, wrapper 중 어디인지 적습니다. 그다음 같은 작은 도구 동작을 CLI와 IDE에서 비교합니다. 그 후 버전을 확인합니다. 재시작, 업데이트, 재설치, 특정 버전으로 되돌리기는 증거를 보존한 뒤에 해도 늦지 않습니다.
IDE만 실패하고 CLI가 작동하면 작업은 CLI로 계속 진행할 수 있습니다. CLI와 IDE가 같은 세션에서 모두 실패하면 IDE만 탓하지 말고 세션을 되돌리세요. 깨끗한 새 세션에서도 같은 작은 동작이 실패할 때 issue나 support ticket을 준비하면 됩니다.
한국어 환경에서는 “로그아웃 후 재인증”이나 “세션 재시작”이 먼저 떠오르기 쉽습니다. 인증이나 billing 문구가 실제로 보이지 않는다면, 그것은 보조 확인일 뿐입니다. 이 exact 400의 중심은 도구 기록과 message shape입니다.
직접 만든 API 클라이언트라면 messages 배열을 보세요

agent framework, IDE integration, backend tool runner를 만들고 있다면 원인은 사용자의 프롬프트보다 messages 배열에 있을 가능성이 큽니다. assistant가 한 turn에서 하나 이상의 tool_use를 냈다면, 클라이언트는 도구를 실행한 뒤 다음 user message에 결과를 돌려줘야 합니다. 실행은 병렬이어도 순차여도 되지만, 반환 형태는 엄격합니다.
지켜야 할 규칙은 세 가지입니다. 모든 tool_use.id에는 대응하는 tool_result.tool_use_id가 있어야 합니다. 같은 assistant turn에서 나온 결과는 다음 user message 하나에 모아야 합니다. 그 user message에 일반 텍스트도 들어간다면 tool_result 블록이 먼저 와야 합니다. 결과 앞에 “결과를 받았습니다” 같은 문장을 넣는 구현은 사람에게는 자연스럽지만 API에는 깨진 형태입니다.
| 클라이언트 실수 | 왜 실패하는가 | 수정 |
|---|---|---|
tool_result 하나가 빠짐 | assistant가 요청한 도구 호출이 닫히지 않음 | 각 ID에 결과를 주거나 손상된 tool turn 전체를 replay history에서 제거 |
| 결과를 여러 user message로 나눔 | 한 assistant turn의 결과 세트가 분리됨 | 다음 user message 하나에 모든 결과를 모음 |
텍스트가 tool_result 앞에 있음 | 결과 블록이 먼저 와야 함 | 모든 결과를 먼저 두고 필요한 설명을 뒤에 둠 |
| history compaction이 tool block을 삭제 | 짝과 순서가 깨짐 | tool_use / tool_result 쌍을 통째로 보존하거나 통째로 제거 |
로그에 필요한 것은 shape이지 비밀이 아닙니다. role 순서, block type, tool ID, 결과 수, 결과 위치를 확인하면 충분합니다. API key, token, 개인 파일 내용, 고객 데이터, 기밀 transcript는 로그에 넣지 마세요. tool runner 가까이에 validator를 두면 잘못된 request를 API에 보내기 전에 막을 수 있습니다.
병렬 실행은 가능하지만 결과 반환은 엄격합니다
병렬 tool use가 금지된 것은 아닙니다. Claude는 한 assistant message에서 여러 tool call을 요청할 수 있습니다. 클라이언트는 이를 동시에 실행할 수도 있고, 외부 시스템이 불안정하면 순차로 실행할 수도 있습니다. API가 엄격하게 보는 것은 실행 방식이 아니라 결과가 대화에 돌아오는 방식입니다.
따라서 “앞으로 병렬로 실행하지 말라”는 조언만으로는 부족합니다. 실행을 하나씩 하더라도 serializer가 ID를 잃어버리거나, 결과를 여러 message로 나누거나, 텍스트를 앞에 두거나, 오래된 history를 잘못 압축하면 같은 오류가 납니다. 반대로 결과를 모두 모아 올바르게 반환한다면 병렬 실행도 유효합니다.
disable_parallel_tool_use는 실제 클라이언트 제한이 있을 때만 사용하세요. side effect가 있는 도구, 동시에 쓰면 깨지는 외부 시스템, 아직 안정적인 aggregator가 없는 runner라면 합리적입니다. 하지만 이 옵션은 message shape 규칙을 대신하지 않습니다. 단일 tool call에서도 matching result는 올바른 위치에 있어야 합니다.
production runner라면 assistant tool_use.id마다 matching result가 있는지, 여분의 tool_result가 없는지, 한 turn의 결과가 다음 user message에 모여 있는지, tool_result가 text보다 앞에 있는지, replayed history가 필요한 tool/thinking block을 삭제하지 않았는지 확인해야 합니다.
긴 세션, 중단, 히스토리 압축이 재발을 만든다
긴 Claude Code 세션은 단순한 텍스트가 아니라 기계적 상태를 함께 갖고 있습니다. tool run을 중간에 멈췄거나, streaming response가 끊겼거나, IDE가 반쪽짜리 상태를 저장했거나, 사용자가 히스토리를 편집했거나, framework가 messages를 압축했다면 다음 request는 겉보기와 달리 구조적으로 깨져 있을 수 있습니다.
재발할 때는 “또 병렬로 불렀나”보다 “직전에 transcript가 어떻게 바뀌었나”를 보세요. 도구 실행을 멈췄는지, 오래된 transcript를 새 세션에 붙였는지, compaction이 tool result를 삭제했는지, tool set이 바뀌었는지, user message 앞쪽에 텍스트가 삽입됐는지 확인합니다.
| 상황 | 위험 | 안전한 회복 |
|---|---|---|
| tool run을 중간에 멈춤 | 반쪽짜리 tool state가 남음 | 그 turn 이전으로 rewind 후 작은 동작으로 검증 |
| history를 편집하거나 압축함 | 필요한 tool/thinking block이 빠짐 | human task summary로 시작하고 transcript는 복사하지 않기 |
| IDE만 실패함 | extension state 또는 bridge 문제 | CLI와 비교하고 version, 최소 실패 동작을 기록 |
| 앱이 stored messages를 replay함 | serializer가 순서나 ID를 바꿈 | API call 직전 exact message array 검증 |
“다시 시도해”, “천천히 해”, “한 번에 하나만 해”라는 프롬프트는 가끔 증상을 우회할 수 있지만 손상된 history를 고치지는 않습니다. 안정적인 해결은 손상된 turn 전으로 돌아가거나 API request가 tool result protocol을 다시 만족하게 만드는 것입니다.
다른 400과 다른 Claude 오류를 분리하세요
HTTP 400이라고 모두 같은 문제가 아닙니다. extra inputs, unsupported role, invalid system, malformed JSON, 모델 파라미터 오류는 request validation 문제일 수 있으며, tool/result history mismatch가 아닐 수 있습니다. 정확한 문구가 API Error: 400 due to tool use concurrency issues인지 먼저 보세요.
| 증상 | 더 맞는 분기 |
|---|---|
| extra inputs, unsupported role, invalid system, malformed JSON이 포함된 400 | request schema / parameter validation |
| tool call, edited history, long session 뒤의 400 | tool/result 또는 thinking-block mismatch |
| 429 또는 rate limit reached | account, workspace, model pressure, quota |
529 overloaded_error | capacity와 bounded retry |
| 500 또는 504 | server error, timeout, request_id, status check |
API Error: Connection error | network, VPN, proxy, DNS, TLS, SDK timeout |
| auth, billing, credits 문구 | account, project, organization, payment, credential |
Claude Status는 확인할 수 있지만 이 exact 400의 주된 증거는 아닙니다. 2026년 7월 4일 저장된 status snapshot은 Claude API와 Claude Code가 operational임을 보여 주었습니다. 그것은 당시의 전역 장애 여부를 보는 자료일 뿐, 로컬 IDE 상태나 messages 배열이 올바르다는 증명은 아닙니다.
issue나 support 전에 증거 패킷을 남기세요

좋은 증거는 비밀을 포함하지 않아도 됩니다. Claude Code version, IDE extension version, 실행 표면, 정확한 오류 문구, 시간과 timezone, 작업 종류, 일반 채팅 동작 여부, /rewind 또는 Esc 두 번의 결과, CLI와 IDE 비교, 직접 만든 클라이언트라면 민감정보를 제거한 message shape를 남기세요.
보내지 말아야 할 것도 분명합니다. API key, token, 개인 파일, 고객 데이터, 전체 기밀 transcript는 필요 없습니다. serializer 문제에서는 assistant turn의 tool_use ID, 다음 user message의 tool_result ID, 결과가 나뉘었는지, 누락됐는지, 텍스트 뒤에 놓였는지만으로도 충분히 진단할 수 있습니다.
같은 습관은 재발도 줄입니다. 오래된 tool turn을 손으로 삭제하지 마세요. tool_result 앞에 자연어 요약을 끼워 넣지 마세요. 한 assistant turn의 results를 여러 message로 나누지 마세요. status가 green이라고 request shape도 맞다고 판단하지 마세요. 새 세션으로 갈 때는 손상된 history가 아니라 사람이 읽을 수 있는 요약을 가져가세요.
FAQ
/rewind, Esc 두 번, /clear, 새 세션 중 무엇을 먼저 써야 하나요?
먼저 /rewind 또는 Esc 두 번입니다. 손상된 tool turn 이전으로 돌아가면서 유효한 작업 컨텍스트를 더 많이 보존합니다. /clear와 새 세션은 작은 검증 동작이 계속 실패할 때 사용하세요.
일반 채팅은 되는데 파일 도구만 실패하는 이유는 무엇인가요?
일반 채팅은 tool/result pairing이 필요하지 않습니다. 파일 읽기, 편집, bash, search는 tool state에 의존합니다. ID, 순서, block type이 깨지면 도구 동작만 실패할 수 있습니다.
정말 도구를 너무 많이 동시에 실행했다는 뜻인가요?
항상 그렇지는 않습니다. 실제 multi-tool turn 뒤에도 생길 수 있지만, 중단, 편집, history compaction, extension state, 누락된 result, 분리된 result, text before tool_result 뒤에도 생깁니다.
API key를 바꿔야 하나요?
이 exact error에서는 첫 조치가 아닙니다. 새 key는 malformed message history를 고치지 않습니다. error body나 account evidence가 auth branch를 가리킬 때만 credentials를 다룹니다.
parallel tool use를 끄면 해결되나요?
클라이언트가 여러 결과를 안전하게 모을 수 없거나 side effect가 있는 도구를 다룰 때는 도움이 됩니다. 그래도 tool_result의 대응과 순서 규칙은 계속 지켜야 합니다.
Claude Status도 확인해야 하나요?
여러 경로가 동시에 실패한다면 확인하세요. 하지만 exact 400이 그대로라면 중심은 status가 아니라 rewind와 message-shape repair입니다.
GitHub issue나 support ticket에는 무엇을 적어야 하나요?
version, surface, exact error text, timestamp, operation type, ordinary chat 상태, /rewind 결과, CLI versus IDE, sanitized message shape를 적으세요. key, token, 개인 파일, 전체 transcript는 보내지 마세요.
현재 세션을 언제 포기해야 하나요?
/rewind 후 같은 작은 tool action이 한두 번 더 같은 exact error를 내면 증거를 남기고 깨끗한 세션으로 이동하세요. 가져갈 것은 요약이지 손상된 tool history가 아닙니다.



