Claude API18 min

Claude Code API Error 400: обновить или восстановить историю инструментов

Исправьте Claude Code API Error 400 due to tool use concurrency issues: сначала проверьте ветку Opus 4.7/4.8 до v2.1.156, затем выполните rewind или аудит каждого tool_result.

Yingtu AI Editorial
Yingtu AI Editorial
YingTu Editorial
4 июл. 2026 г.
Обновлено 15 июл. 2026 г.
18 min
Claude Code API Error 400: обновить или восстановить историю инструментов
yingtu.ai

Содержание

Заголовки не найдены

Если Claude Code показывает API Error: 400 due to tool use concurrency issues, инструментальная история диалога стала несогласованной. Не меняйте key, не покупайте квоту, не переключайте провайдера и не очищайте всю сессию первым действием.

По состоянию на 15 июля 2026 года документация Anthropic выделяет узкую ветку: для Opus 4.7 или 4.8 в Claude Code раньше v2.1.156 сначала обновите Claude Code. Эти сборки могут создавать mismatch при обычном использовании tools, а /rewind не всегда очищает состояние. Для других версий и моделей сохраните контекст задачи, выполните /rewind или двойной Esc до поврежденного turn и проверьте один небольшой tool action.

Если вы владеете API loop, сопоставьте каждый assistant tool_use ровно с одним tool_result, верните полный набор в следующем user message и поставьте результаты перед любым текстом.

ПоверхностьПервое безопасное действиеПризнак успеха
Opus 4.7/4.8 и Claude Code раньше v2.1.156обновить Claude Code и повторить один маленький tool actionто же действие проходит в обновленном клиенте
Другие CLI- или IDE-сессии Claude Codeсохранить задачу, rewind до поврежденного turn, повторить одно действиеновый tool turn завершается без 400
Собственный Anthropic clientпроверить последний assistant tool turn и следующий пакет результатоввсе ID совпали, validator пуст, один replay успешен

Если применимое обновление или один чистый rewind не спасли то же простое действие, прекратите цикл восстановления. Сохраните версию, поверхность, точный error и очищенную форму двух проблемных turns; затем начните с human summary без поврежденного transcript или отправьте ограниченный bug report.

Что означает именно этот 400

Фраза tool use concurrency issues легко сбивает с толку. Она звучит так, будто пользователь просто запустил слишком много инструментов одновременно. В этом случае более полезная трактовка уже: API получил состояние диалога, которое не может продолжить. Claude Code связывает точную ошибку с mismatch в tool use или thinking block, а обычный HTTP 400 в Claude API относится к invalid_request_error, то есть к формату или содержанию запроса.

Разрыв появляется двумя путями. В Claude Code длинная сессия может пережить остановленный tool run, прерванный stream, редактирование истории или состояние IDE-расширения, где следующий запрос ссылается на инструментальный блок, который уже нельзя корректно закрыть. В собственном Messages API клиенте чат может выглядеть понятным человеку, но быть недопустимым для модели: один tool_result отсутствует, результаты разделены по нескольким user messages, текст поставлен перед результатами, либо tool_use_id не совпадает.

Поэтому нормальный чат иногда продолжает отвечать, а file read, edit, bash или search ломаются. Обычный текст не требует пары tool call / result. Инструментальный turn требует строгой структуры. Если лечить это как network issue, billing issue или generic bad request, вы будете проверять не тот слой.

Восстановите сессию Claude Code без потери работы

Сначала сохраните человеческий контекст. Запишите текущую задачу, изменяемые файлы, последнюю команду или tool action, точный текст ошибки, время с часовым поясом и поверхность, где ошибка появилась. Это не нужно превращать в полный transcript. Цель другая: сохранить то, что можно безопасно перенести, если сессию все-таки придется начать заново.

Затем запишите claude --version. Если вы используете Opus 4.7/4.8 в Claude Code раньше v2.1.156, сначала обновитесь: не доказывайте известное исключение несколькими попытками /rewind. В остальных случаях сравните один простой tool action в CLI и в VS Code, Cursor или другой оболочке. Разница между CLI и IDE помогает понять, повреждено ли состояние расширения или вся текущая conversation history.

Используйте /rewind, чтобы вернуться до поврежденного tool turn. Claude Code также описывает двойной Esc как способ отката в диалоге. После отката не давайте большой смешанный prompt, где нужно читать, редактировать, запускать тесты и искать документацию одновременно. Дайте одну чистую команду: прочитать файл, вывести директорию или выполнить короткий безопасный shell command. Если она проходит, продолжайте работу маленькими связными шагами.

Новая сессия нужна только после провала этого восстановления. И даже тогда не переносите весь старый transcript. Перенесите краткое резюме задачи, список файлов, последний доверенный результат и очищенную ошибку. Копирование поврежденной истории инструментов часто переносит саму причину 400 в новую сессию.

IDE, Cursor и VS Code требуют отдельной проверки

В IDE-ветке ошибка часто выглядит особенно странно: обычные ответы появляются, а любая операция с файлами возвращает 400. Это не доказывает, что пользователь сам вызвал несколько tools параллельно. Иногда IDE-расширение хранит частичное состояние, мост между editor и CLI меняет порядок сообщений, remote environment отдает не ту версию клиента, или расширение воспроизводит старый поврежденный turn.

Практичный порядок такой. Сначала запишите поверхность: Claude Code CLI, VS Code, Cursor, remote SSH, WSL, terminal multiplexer или другой wrapper. Затем сравните один и тот же маленький tool action в CLI и IDE. После этого проверьте версии Claude Code и расширения. Перезапуск, update или reinstall имеют смысл, но только после того, как вы сохранили evidence и не уничтожили рабочую CLI-сессию.

Если IDE ломается, а CLI работает, продолжайте срочную работу в CLI и отдельно изолируйте extension path. Если и CLI, и IDE ломаются внутри той же сессии, сначала откатывайте сессию. Если новая чистая сессия с тем же маленьким действием снова падает, тогда уже собирайте bug packet для поддержки или maintainer issue.

Старые обсуждения иногда советуют downgrade конкретной версии расширения. Относитесь к этому как к историческому контексту. Устойчивое правило другое: сравнить поверхности, сохранить evidence, выполнить официальный путь восстановления и только потом менять extension installation.

Если вы пишете Anthropic клиент, смотрите на messages

В собственном agent framework, IDE integration или backend tool runner проблема обычно сидит не в поведении пользователя, а в форме messages. Предыдущий assistant turn может содержать несколько tool_use blocks. Ваш runner может выполнить их параллельно или последовательно. Но следующий user message должен вернуть полный набор соответствующих tool_result blocks.

Три правила нельзя нарушать. Во-первых, каждый tool_use.id должен получить один matching tool_result.tool_use_id. Во-вторых, результаты для одного assistant turn должны вернуться вместе в следующем user message. В-третьих, если в этом user message есть и результаты, и обычный текст, tool_result blocks должны идти раньше текста. Текст вроде “я получил результат” перед результатами может сделать человеческий transcript понятным, но API request недопустимым.

Ошибка клиентаПочему это ломает запросИсправление
отсутствует один tool_resultassistant запросил инструмент, но результат не закрытвернуть результат для каждого ID или удалить всю поврежденную tool-пару из replay history
результаты разделены по нескольким user messagesмодель ждет единый result set после assistant tool turnобъединить все результаты этого turn в одну user message
текст стоит перед tool_resultрезультатные блоки должны идти первымипоставить все tool_result blocks перед любым текстом
failed или skipped call исчезаетassistant call остается незакрытымвернуть matching result с is_error: true
ID дублируется или отсутствовал в предыдущем turnresult нельзя связать один-к-одномуотклонить unknown ID и устранить duplicate
history compaction удалил часть tool blocksсжатая история нарушила парностьсжимать только целые пары tool_use/tool_result или начинать с human summary

Логируйте форму, а не секреты. Для отладки достаточно видеть roles, block types, ids, result count and order. Не логируйте API keys, tokens, private file contents, customer data или proprietary payloads. Хороший validator рядом с tool runner может остановить неверный request до отправки.

Проверьте поврежденный turn валидатором перед replay

Изолируйте последний assistant message с клиентскими tool_use и следующий user message. Эта функция проверяет missing, duplicate и unknown IDs, порядок блоков, ошибочные или пропущенные вызовы и незавершенный server tool:

hljs ts
type Block = { type: string; id?: string; tool_use_id?: string; is_error?: boolean };
type Message = { role: "assistant" | "user"; content: Block[] };

export function auditToolTurn(
  assistant: Message,
  nextUser: Message,
  options: { failedOrSkippedIds?: ReadonlySet<string>; hasPendingServerTool?: boolean } = {},
): string[] {
  const problems: string[] = [];
  const calls = assistant.content.filter((b) => b.type === "tool_use");
  const results = nextUser.content.filter((b) => b.type === "tool_result");
  const callIds = calls.flatMap((b) => b.id ? [b.id] : []);
  const resultIds = results.flatMap((b) => b.tool_use_id ? [b.tool_use_id] : []);
  const count = (ids: string[], id: string) => ids.filter((x) => x === id).length;
  if (assistant.role !== "assistant") problems.push("Expected an assistant tool-use turn");
  if (nextUser.role !== "user") problems.push("Tool results must be in the next user message");
  for (const id of new Set(callIds)) {
    if (count(callIds, id) > 1) problems.push(`Duplicate tool_use id: ${id}`);
    if (count(resultIds, id) === 0) problems.push(`Missing tool_result: ${id}`);
    if (count(resultIds, id) > 1) problems.push(`Duplicate tool_result: ${id}`);
  }
  for (const id of new Set(resultIds)) if (!callIds.includes(id)) problems.push(`Unexpected tool_result: ${id}`);
  const firstNonResult = nextUser.content.findIndex((b) => b.type !== "tool_result");
  if (firstNonResult >= 0 && nextUser.content.slice(firstNonResult + 1).some((b) => b.type === "tool_result")) {
    problems.push("Every tool_result must appear before text or other user content");
  }
  for (const id of options.failedOrSkippedIds ?? []) {
    const result = results.find((b) => b.tool_use_id === id);
    if (result && result.is_error !== true) problems.push(`Failed or skipped call must use is_error: true: ${id}`);
  }
  if (options.hasPendingServerTool && nextUser.content.some((b) => b.type !== "tool_result")) {
    problems.push("Pending server tool: next user message must contain client tool_result blocks only");
  }
  return problems;
}

Пустой массив означает, что изолированная пара прошла эти проверки; это не доказывает сохранность более ранних thinking blocks. Исправьте producer или stored record и повторите replay один раз, а не отправляйте тот же malformed array снова.

Параллельное выполнение разрешено, но сериализация строгая

Параллельность и формат возврата — разные вопросы. Claude может попросить несколько инструментов в одном assistant turn. Ваш код может выполнить их одновременно, потому что это быстрее, или последовательно, потому что внешняя система хрупкая. Для API важно другое: когда результаты возвращаются в диалог, они должны образовать полный, упорядоченный, matching set.

Поэтому совет “просто не запускайте параллельно” недостаточен. Если serializer теряет один ID, вставляет summary before results, делит ответы по messages или меняет старую history, ошибка останется даже при последовательном исполнении. И наоборот, корректно собранные parallel results могут быть валидны, если они возвращены вместе и перед текстом.

disable_parallel_tool_use стоит использовать только при реальном ограничении клиента: side-effect tools, fragile external systems или отсутствие надежного aggregator. Параметр находится внутри tool_choice, а не на верхнем уровне request:

hljs json
{
  "tool_choice": {
    "type": "auto",
    "disable_parallel_tool_use": true
  }
}

Это не заменяет правильный tool_result порядок. Даже один tool call требует matching result в правильном месте.

Для production-клиента полезен короткий checklist: каждый assistant tool_use.id имеет matching result; нет лишнего tool_result; все results для одного turn находятся в следующем user message; tool_result blocks идут перед text; replayed history не удаляет thinking, tool или result blocks, на которые модель еще опирается.

Pending server tool меняет содержимое следующего user message

Обычно после всех tool_result разрешен дополнительный текст. Но если тот же assistant turn содержит незавершенный server tool, следующий user message должен содержать только принадлежащие клиенту tool_result blocks. Текст после них может преждевременно завершить turn и вызвать 400 с именем незавершенного server tool.

Состояние assistant turnЧто разрешено в следующем user message
Только client toolsВсе matching results первыми; затем допустимый текст
Client tools и pending server toolТолько matching client tool_result blocks
Нет незавершенных client callsОбычный user message по остальному контракту

Не создавайте фиктивный client result для server tool. Сохраните server block, верните только реально выполненные client results и позвольте поддерживаемому server-tool loop продолжиться.

Почему длинные сессии и прерывания возвращают ошибку

Длинная Claude Code сессия накапливает не только текст, но и машинное состояние. Если tool action был остановлен, stream оборвался, IDE сохранила половину turn, пользователь вручную отредактировал history или framework сжал messages, следующий запрос может стать структурно недопустимым. Это выглядит как внезапная 400, хотя причина была создана несколькими шагами раньше.

При повторении ошибки спрашивайте не “почему Claude снова параллелит инструменты”, а “что произошло с transcript перед ошибкой”. Была ли остановка? Было ли редактирование? Был ли compaction? Копировали ли старую историю в новую сессию? Менялся ли набор tools? Не вставлял ли клиент обычный текст перед result blocks?

СитуацияВероятный рискБолее надежное восстановление
tool run был остановленв history остался частичный tool stateоткатиться до tool turn и проверить одним действием
history вручную очищали или сжималиудалены обязательные tool/thinking blocksначать с human task summary, не с transcript
падает только IDEсломан extension state или bridgeсравнить CLI, сохранить version и minimal failing action
приложение replay-ит stored messagesserializer меняет order или idsвалидировать exact message array перед API call

Повторные prompts вроде “try again”, “avoid concurrency” или “use one tool at a time” могут иногда обойти симптом, но не чинят поврежденную history. Надежное решение — восстановить checkpoint или исправить serializer.

Другие 400 и другие ошибки Claude надо отводить отдельно

Точный текст ошибки решает ветку. Если response содержит другой 400, например unsupported role, extra inputs are not permitted, invalid system placement, malformed JSON или недопустимый параметр модели, это тоже request-format issue, но не тот же tool-history mismatch. В таком случае /rewind может помочь только если поврежденная history реально участвует; чаще нужно чинить request schema.

СимптомПодходящая ветка
400 с extra inputs, unsupported role, invalid system или malformed JSONschema validation и параметры запроса
400 после tool calls, edited history или long sessiontool/result или thinking-block mismatch
429 или rate limit reachedвладелец Claude rate limit: лимиты, allowance и quota
529 overloaded_errorвладелец Claude 529: capacity и bounded retry
500 или 504server error, timeout, request evidence и status check
API Error: Connection errorвладелец connection error: network, VPN, proxy, DNS, TLS или timeout
auth, billing, creditsаккаунт, проект, организация, оплата или credential route

Status page полезна, но не является proof для этого exact 400. При проверке 15 июля 2026 года в 13:48 UTC+8 официальный summary показывал Claude API и Claude Code operational без активного incident. Это датированная проверка ветки, а не гарантия и не доказательство корректности локальной IDE-сессии или messages array. При массовом сбое проверяйте live status заново; для exact 400 возвращайтесь к версии, error body и tool history.

Что сохранить перед issue или support ticket

Хороший пакет доказательств помогает другому инженеру воспроизвести проблему без доступа к вашим секретам. Укажите Claude Code version, IDE extension version, поверхность выполнения, точный текст ошибки, timestamp with timezone, тип операции, ordinary chat behavior, результат /rewind или двойного Esc, сравнение CLI versus IDE и sanitized message shape для API-клиента.

Не отправляйте API key, token, private file contents, customer data или полный confidential transcript. Для serializer bug важна структура: какие tool_use ids были в assistant turn, какие tool_result ids вернулись в следующем user message, были ли results split, missing или placed after text.

Та же дисциплина снижает повторение ошибки. Не редактируйте старые tool turns руками. Не вставляйте natural-language summary перед tool_result. Не делите results одного assistant turn на несколько messages. Не считайте green status доказательством правильной request shape. Если нужна новая сессия, переносите human summary и безопасные ссылки на файлы, а не сломанную историю.

FAQ

Что выбрать: /rewind, Esc два раза, /clear или новая сессия?

Сначала /rewind или двойной Esc, потому что они возвращают вас к состоянию до поврежденного tool turn и сохраняют больше полезного контекста. /clear и новая сессия нужны только после провала маленькой проверки в той же сессии.

Почему обычный чат работает, а file tools падают?

Потому что текстовый ответ не требует tool/result pairing. File read, edit, bash и search зависят от tool state. Если ids, order или block types не совпали, tool action может падать, а обычный ответ продолжать работать.

Это точно слишком много параллельных инструментов?

Нет. Ошибка может появиться после настоящего multi-tool turn, но также после interrupt, edited history, extension cache, missing result, split result или text before tool_result. Чинить нужно transcript structure.

Нужно ли менять API key?

Не первым шагом. Новый ключ не исправляет malformed message history. Меняйте credentials только если error body или account evidence указывает на auth branch.

Стоит ли отключить parallel tool use?

Только если ваш клиент не умеет безопасно собирать multiple results или tools имеют side effects. Поместите disable_parallel_tool_use: true внутри tool_choice. Даже после отключения parallel execution порядок tool_result остается обязательным.

Что вернуть, если tool завершился ошибкой или был пропущен?

Верните tool_result для соответствующего tool_use_id, установите is_error: true и добавьте безопасное описание ошибки. Не удаляйте вызов из result set: полнота относится к протоколу, а не к успеху каждой операции.

Почему текст после results иногда вызывает server-tool 400?

Текст обычно допустим после client results, но не пока в том же assistant turn остается pending server tool. В смешанном состоянии следующий user message должен содержать только client tool_result blocks.

Нужна ли Claude Status?

Да, но как sanity check. Если несколько маршрутов одновременно падают, проверьте live status. Если точный error остается 400 tool-history mismatch, восстановление все равно идет через rewind или message-shape repair.

Что писать в GitHub issue или ticket?

Версию, поверхность, точный error text, время, operation type, работает ли ordinary chat, помог ли /rewind, CLI versus IDE, и sanitized message shape. Секреты, приватные файлы и полный transcript не прикладывайте.

Когда прекратить спасать текущую сессию?

После /rewind и одного-двух простых tool checks, которые воспроизводят тот же exact error. Сохраните evidence, начните чистую сессию с human summary и не импортируйте поврежденную tool history.

Теги

Поделиться статьей

XTelegram