Содержание
- 1. Что на самом деле говорит эта ошибка
- 2. Предыстория: extended thinking и механизм signature
- 3. Почему это происходит — 5 первопричин
- 4. Три способа исправить прямо сейчас (для пользователей Claude Code)
- 5. Для разработчиков: предотвращение в своем приложении (API/SDK)
- 6. Как отличить от похожих ошибок
- 7. Чек-лист предотвращения повторов
- Итог
- FAQ
Бывало ли у вас так, что во время работы в Claude Code внезапно появляется эта ошибка и сессия полностью перестает отвечать?
API Error: 400 messages.3.content.40: `thinking` or
`redacted_thinking` blocks in the latest assistant message
cannot be modified. These blocks must remain as they were
in the original response.
Самое неприятное: стоит ей появиться, и каждый последующий ввод вызывает ту же ошибку. Вы печатаете, жмете Enter — снова те же 400. Сессия впадает в состояние "зависания". Это известный баг с несколькими открытыми тикетами в официальном репозитории Anthropic (#10199, #12225, #13012, #22278, #63147 и другие).
Сразу о главном: причина в том, что блоки extended thinking повреждаются при повторной отправке истории разговора. Блоки thinking несут криптографическую signature, и API проверяет подпись на соответствие содержимому побайтово. Когда Claude Code пересобирает историю с багом — например, обнуляет текст thinking, но сохраняет signature — подпись больше не совпадает, и API отклоняет запрос. Самый быстрый выход — "дважды нажать Esc и сделать /rewind к контрольной точке" либо начать новую сессию. В этой статье разберем механизм, 5 первопричин, 3 способа исправления для пользователей, меры для разработчиков и предотвращение повторов.
Полная картина ошибки с блоком thinking
— Если signature не совпадает, API отклоняет весь разговор
Известный баг с несколькими тикетами в официальном репозитории Anthropic.
Суть: строгое правило API, что "блоки thinking должны оставаться точно такими, как в исходном ответе."
1. Что на самом деле говорит эта ошибка
Простыми словами сообщение говорит: "Блоки thinking или redacted_thinking в последнем сообщении ассистента нельзя изменять. Эти блоки должны оставаться такими, какими были в исходном ответе."
То есть API сообщает вам: "Блок thinking внутри истории разговора, которую вы (клиент) мне прислали, отличается от того, что я вернул в прошлый раз. Он был изменен. Поэтому я его не приму." Claude API исходит из того, что в многоходовых разговорах вы "включаете предыдущий ответ в историю и отправляете его обратно без изменений", причем именно блок thinking несет строгое ограничение "не менять ни единого символа". messages.3.content.40 — это позиционная информация: проблема в "41-м блоке контента 4-го сообщения".
Важный момент: в большинстве случаев это НЕ ошибка в вашем коде или промпте. Главная причина — баг в том, как Claude Code пересобирает историю разговора (сессионный JSONL), который повреждает блоки thinking. Так что незачем мучиться вопросом "может, я что-то делаю не так?" — это известный баг с обходными путями.
2. Предыстория: extended thinking и механизм signature
Почему именно блок thinking настолько строг? Причина — в том, как работает extended thinking.
Когда Claude отвечает с включенным extended thinking, он генерирует "блок thinking" перед ответом. Это промежуточное рассуждение Claude — внутреннее "как он думал", что повышает качество финального ответа. Этому блоку присваивается криптографическая signature — нечто вроде цифровой подписи, гарантирующей, что "это содержимое thinking действительно сгенерировано Claude и не было изменено."
В многоходовых разговорах и циклах tool use весь предыдущий обмен каждый раз отправляется обратно в API. Блоки thinking тоже должны быть отправлены, но signature вычисляется по "всему исходному тексту thinking" — поэтому если текст изменится хотя бы на один символ, проверка подписи провалится. Из соображений безопасности API отклоняет блоки thinking, чья signature не совпадает. В этом и суть ошибки 400.
Зачем нужна signature
Запрет на изменение блоков thinking блокирует prompt injection и подделку рассуждений. Это механизм безопасности, защищающий факт того, что "Claude действительно так думал" — у строгости есть своя причина.
3. Почему это происходит — 5 первопричин
Конкретные сценарии несовпадения signature сводятся к пяти — на основе официальных тикетов Anthropic и сообщений сообщества.
Пять первопричин несовпадения signature
Общий знаменатель: если блок thinking отличается от исходного хотя бы на один байт, вы всегда получаете 400.
Причины 1–4 — это баги Claude Code / прокси; причина 5 — проблема самостоятельной реализации.
4. Три способа исправить прямо сейчас (для пользователей Claude Code)
Когда сессия зависла, попробуйте три метода в порядке скорости восстановления.
Три способа по скорости восстановления
/rewind. Вернитесь к контрольной точке перед поврежденным ходом. Лучший вариант — восстанавливает с сохранением контекста./clear или запуск новой сессии. Самый надежный, но теряет контекст. Сначала зафиксируйте важную работу заметкой/коммитом.
Сначала пробуйте СПОСОБ 1 (Esc×2 / rewind). Если не помогло — СПОСОБ 2. Если нужно сохранить контекст — СПОСОБ 3.
И всегда обновляйте Claude Code до последней версии (Anthropic исправляет это постепенно).
О СПОСОБЕ 3: сообщество выпустило инструмент "Claude Code thinking blocks fix" (например, miteshashar/claude-code-thinking-blocks-fix на GitHub). Он удаляет из сессионного JSONL все блоки контента thinking, искореняя проблему signature и сохраняя историю разговора. Его стоит взять на вооружение, если вы часто сталкиваетесь с этим или активно работаете в долгих сессиях. Но это неофициальный инструмент, так что используйте на свой риск — сделайте резервную копию JSONL перед запуском.
Самое важное постоянное решение — "держать Claude Code на последней версии." Выполняйте claude update или следуйте официальной процедуре обновления. Anthropic постепенно выпускает "защитный механизм, который обнаруживает блоки thinking с пустым текстом и signature и убирает их перед отправкой" для этой серии багов (#10199, #12225, #63147 и др.). Старые версии сталкиваются с этим чаще.
5. Для разработчиков: предотвращение в своем приложении (API/SDK)
Если вы строите приложение, которое само обращается к Claude API/SDK (extended thinking + tool use), вы столкнетесь с той же ошибкой в собственной реализации. Предотвратить ее помогают три принципа.
// BAD: deleting/altering thinking blocks before sending back
const history = previousMessages.map(m => ({
...m,
content: m.content.filter(b => b.type !== 'thinking') // mismatches signature
}));
// GOOD pattern 1: keep thinking blocks "exactly as-is"
// Push the assistant message from the API into history untouched
messages.push(assistantMessageFromApi); // keep the signature intact
// GOOD pattern 2: "fully drop" thinking from past turns
// Don't send empty text + signature; omit the block entirely
const clean = previousMessages.map(m => {
if (m.role !== 'assistant') return m;
return {
...m,
content: m.content.filter(b =>
b.type !== 'thinking' && b.type !== 'redacted_thinking'
),
};
});
// NOTE: do NOT drop them from the "latest" assistant message (during tool use)
Три принципа: ① Полностью сохраняйте подписанный текст thinking и возвращайте его в неизменном виде. ② Если не отправляете thinking из прошлых ходов, удаляйте блок целиком (пустой текст с signature — наихудший вариант). ③ Добавьте защитный механизм на этапе сборки запроса, который обнаруживает блоки thinking с "пустым текстом, но наличием signature" и убирает их.
Железное правило для циклов tool use
В циклах extended thinking + tool use (tool_use → tool_result) никогда не меняйте блок thinking "последнего" сообщения ассистента. Следующий запрос, возвращающий tool_result, должен включать предшествующие thinking + tool_use ровно в том виде, как есть. Если вы используете Claude Agent SDK или Vercel AI SDK, убедитесь, что библиотека обрабатывает это корректно.
6. Как отличить от похожих ошибок
Есть несколько связанных с thinking ошибок 400, которые легко спутать. Различайте три основные.
| Сообщение об ошибке | Значение | Основное решение |
|---|---|---|
| thinking blocks ... cannot be modified | Тема этой статьи. Несовпадение signature и содержимого | /rewind, новая сессия, обновление до последней версии |
| Invalid signature in thinking block | Сама signature недействительна (часто из-за изменения прокси) | Проверить конфигурацию прокси, подключиться к API напрямую |
| The final block in an assistant message cannot be thinking | Сообщение ассистента заканчивается на thinking (в конце нужен text или tool_use) | Исправить структуру сообщения, обновить SDK |
Общая первопричина — "некорректная обработка блоков extended thinking." Для пользователей Claude Code большинство случаев решается через /rewind + обновление до последней версии. Для самостоятельных приложений нужно пересмотреть структуру сообщений и реализацию библиотеки. Если вы идете через прокси (CLIProxyAPI, разные шлюзы), в первую очередь подозревайте, что прокси меняет thinking.
7. Чек-лист предотвращения повторов
Практический чек-лист, чтобы избежать частых повторов.
Пользователям Claude Code: ① Держите его на последней версии через claude update (главная профилактика). ② Периодически сбрасывайте очень длинные сессии через /clear (снижает риск смешивания). ③ Часто коммитьте в git важную работу (восстановимо даже при зависании). ④ Подумайте об инструменте починки JSONL, если повторяется часто. ⑤ Сообщайте о воспроизведениях в официальные тикеты Anthropic (ускоряет исправления).
Разработчикам на API/SDK: ① Кладите сообщения ассистента в историю без изменения ответа API. ② Если убираете прошлый thinking, удаляйте блок целиком (без пустого текста с signature). ③ Добавьте защитный механизм на этапе сборки запроса (обнаружить пустой текст с signature → убрать). ④ Используйте последний официальный SDK и минимизируйте свои переделки сообщений. ⑤ Если вы за прокси, проверьте прозрачность для thinking.
Итог
Ошибка 400 "thinking blocks ... cannot be modified" в Claude Code возникает, когда блоки extended thinking повреждаются при повторной отправке истории и криптографическая signature перестает совпадать с содержимым. Это известный баг с несколькими тикетами в официальном репозитории Anthropic, и в большинстве случаев это не ваша вина. Пять причин: баг возобновления сессии (самая частая), смешивание стримов, логика починки идет вразнос, сторонние прокси и изменение истории в своем приложении.
Для пользователей Claude Code самое быстрое восстановление — ① нажать Esc×2 / /rewind к контрольной точке; если не помогло — ② новая сессия (/clear); чтобы сохранить контекст — ③ инструмент починки JSONL. Самое важное постоянное решение — "обновить Claude Code до последней версии", ведь Anthropic постепенно выпускает защитный механизм. Разработчикам на API/SDK следует соблюдать три принципа: возвращать блоки thinking как есть / полностью удалять их при отказе / добавить защитный механизм.
Похожие материалы: Что такое Claude Agent SDK, Полное руководство по Vercel AI SDK, Что такое Cursor, Рабочий процесс деплоя Claude Code/Cursor.
FAQ
Q. Эта ошибка — ошибка в моем промпте или коде?
A. В большинстве случаев нет. Если она появляется при использовании Claude Code, это почти наверняка известный баг на стороне Claude Code (дефект пересборки истории сессии). В официальном репозитории Anthropic открыто несколько тикетов, и исправления идут. Винить себя не нужно. Только для самостоятельных приложений (прямое обращение к API) стоит пересмотреть свою реализацию.
Q. /rewind не помогает. Что дальше?
A. Запуск новой сессии (/clear) — самый надежный путь. Вы теряете контекст, но гарантированно выходите из зависшего состояния. Сначала сохраните важную работу через git commit или заметки. Если повторяется — обновите Claude Code до последней версии; если все равно происходит, подумайте об инструменте починки JSONL.
Q. Можно ли избежать этого, отключив extended thinking?
A. Технически да, но extended thinking заметно повышает точность на сложных задачах, поэтому отключать его не рекомендуется. Сначала справьтесь через обновление до последней версии + /rewind, и рассматривайте этот вариант лишь как крайнюю меру в особых средах (например, за прокси), где он все равно повторяется.
Q. Безопасен ли инструмент починки JSONL?
A. Он неофициальный, так что используйте на свой риск. Всегда делайте резервную копию сессионного JSONL перед использованием. Механизм — "удалить все блоки контента thinking, сохранив историю разговора", что в принципе безопасно, но официальное решение (обновление до последней версии) остается настоящим выходом.
Q. В моем приложении сочетание tool use с thinking вызывает эту ошибку.
A. Причина в том, что "вы меняете блок thinking последнего сообщения ассистента." Следующий запрос, возвращающий tool_result, должен включать предшествующие блоки thinking + tool_use ровно так, как их вернул API (с signature). Если убираете thinking из прошлых ходов, удаляйте блок целиком (без пустого текста с signature). Последний официальный SDK делает большую часть этого автоматически.