Índice
- 1. Qué dice realmente este error
- 2. Contexto: extended thinking y el mecanismo de "signature"
- 3. Por qué ocurre — 5 causas raíz
- 4. Tres soluciones inmediatas (para usuarios de Claude Code)
- 5. Para desarrolladores: prevenirlo en tu propia app (API/SDK)
- 6. Cómo distinguirlo de errores parecidos
- 7. Checklist para evitar que se repita
- Resumen
- FAQ
¿Estabas trabajando en Claude Code y de pronto aparece este error y la sesión deja de responder por completo?
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.
Si falla la verificación de la signature de un bloque thinking que reenvías, puede aparecer en su lugar este error. Ambos tienen el mismo origen: el bloque thinking ya no es exactamente el de la respuesta original:
API Error: 400 messages.1.content.0:
invalid `signature` in `thinking` block
Lo peor del caso: una vez que aparece, cada entrada posterior dispara el mismo error. Escribes, pulsas Enter y vuelve el mismo 400. La sesión entra en un estado "atascado". Es un bug conocido, con varios issues abiertos en el repositorio oficial de Anthropic (#10199, #12225, #13012, #22278, #63147 y más).
Por adelantado: la causa es "que los bloques de extended thinking se corrompen cuando se reenvía el historial de la conversación". Los bloques de thinking llevan una signature criptográfica, y la API comprueba que los bloques de thinking reenviados no hayan cambiado respecto a la respuesta original. Cuando un bug al reconstruir el historial en Claude Code hace que un bloque difiera del original, la API lo rechaza. La salida más rápida es "pulsar Esc dos veces y volver a un checkpoint con /rewind", o iniciar una sesión nueva. Este artículo cubre el mecanismo, las 5 causas raíz, 3 soluciones para el usuario, contramedidas para desarrolladores y la prevención de recurrencias.
El panorama completo del error de thinking-block
— Si la "signature" no coincide, la API rechaza toda la conversación
Un bug conocido con varios issues en el repo oficial de Anthropic.
La esencia: la regla estricta de la API de que "los bloques de thinking deben permanecer exactamente como en la respuesta original."
1. Qué dice realmente este error
En términos sencillos, el mensaje dice: "Los bloques de thinking o redacted_thinking del último mensaje del asistente no se pueden modificar. Estos bloques deben permanecer tal y como estaban en la respuesta original."
Es decir, la API te está diciendo: "El 'bloque de thinking' que hay dentro del historial de conversación que tú (el cliente) me enviaste difiere de lo que te devolví la última vez. Ha sido modificado. Así que no lo acepto." La API de Claude da por hecho que en conversaciones multi-turno tú "incluyes la respuesta anterior en el historial y la reenvías sin cambios" — y el bloque de thinking en particular tiene una restricción estricta de "no cambiar ni un solo carácter". messages.3.content.40 es información de posición: "el bloque de contenido número 41 del mensaje número 4" es donde está el problema.
El punto importante: en la mayoría de los casos esto NO es un fallo de tu código ni de tu prompt. La causa principal es un bug en cómo Claude Code reconstruye el historial de conversación (el JSONL de la sesión), que corrompe los bloques de thinking. Así que no hace falta atormentarse con "¿lo estaré usando mal?" — es un bug conocido con soluciones.
2. Contexto: extended thinking y el mecanismo de "signature"
¿Por qué solo el bloque de thinking es tan estricto? La razón está en cómo funciona extended thinking.
Cuando Claude responde con extended thinking activado, genera un "bloque de thinking" antes de la respuesta. Es el razonamiento intermedio de Claude — el "cómo pensó" interno que eleva la calidad de la respuesta final. A este bloque se le asigna una signature criptográfica — algo como una firma digital que garantiza "este contenido de thinking fue generado genuinamente por Claude y no ha sido alterado."
En conversaciones multi-turno y bucles de tool-use, todo el intercambio previo se reenvía a la API cada vez, y los bloques de thinking también deben enviarse. Según la documentación oficial, la signature contiene una copia cifrada del thinking completo: la API la usa para verificar que el bloque devuelto lo generó Claude, y el servidor la descifra para reconstruir el thinking original. El texto de thinking que ves es un resumen, y en los modelos más recientes el valor predeterminado (display: "omitted") lo deja vacío. La signature es la misma sea cual sea el ajuste de display, y cualquier texto que pongas en el campo thinking de un bloque omitted se ignora. Por eso la documentación pide devolver los bloques de thinking tal como llegaron, sin modificarlos. Si la signature falta o está dañada, o el bloque ya no coincide con la respuesta original, la API rechaza ese bloque de thinking. Esa es la esencia del error 400.
Por qué existe la signature
Impedir la modificación de los bloques de thinking bloquea el prompt injection y la suplantación de razonamiento. Es un mecanismo de seguridad que protege el hecho de que "Claude realmente pensó esto" — la rigidez tiene su razón de ser.
3. Por qué ocurre — 5 causas raíz
Los escenarios concretos en los que la signature no coincide se agrupan en cinco — sintetizados a partir de los issues oficiales de Anthropic y de reportes de la comunidad.
Cinco causas raíz de que la signature no coincida
El hilo común: si un bloque de thinking difiere del original aunque sea en un byte, siempre obtienes un 400.
Las causas 1 a 4 son bugs de Claude Code o del proxy; la causa 5 es un problema de implementación casera.
4. Tres soluciones inmediatas (para usuarios de Claude Code)
Cuando tu sesión esté atascada, prueba tres métodos por orden de velocidad de recuperación.
Tres soluciones por velocidad de recuperación
/rewind. Retrocede al checkpoint anterior al turno corrupto. La mejor jugada — se recupera preservando el contexto./clear o inicia una sesión nueva. Lo más fiable, pero pierdes el contexto. Anota o haz commit del trabajo importante antes.
Prueba primero la SOLUCIÓN 1 (Esc×2 / rewind). Si falla, la SOLUCIÓN 2. Si necesitas conservar el contexto, la SOLUCIÓN 3.
Y mantén siempre Claude Code en la última versión (Anthropic lo está corrigiendo de forma progresiva).
Nota sobre la SOLUCIÓN 3: la comunidad ha publicado una herramienta "Claude Code thinking blocks fix" (por ejemplo, miteshashar/claude-code-thinking-blocks-fix en GitHub). Elimina todos los bloques de contenido de thinking del JSONL de la sesión, erradicando el problema de la signature y conservando el historial de conversación. Vale la pena adoptarla si lo sufres a menudo o usas mucho sesiones largas. Pero es una herramienta no oficial, así que úsala bajo tu propia responsabilidad — haz una copia de seguridad del JSONL antes de ejecutarla.
La solución permanente más importante es "mantener Claude Code en la última versión". Ejecuta claude update o sigue los pasos oficiales de actualización. El changelog de Claude Code recoge una corrección tras otra en esta familia: el entremezclado de streaming con agentes concurrentes (2.1.47), la eliminación preventiva de signatures obsoletas tras cambiar de modelo o de sesión (2.1.152), la modificación de bloques de thinking con Opus 4.8 (2.1.156) y el descarte de los bloques de thinking con un único reintento tras un error de redacted_thinking (2.1.282). Aun así, se informó de que #63147 seguía reproduciéndose en 2.1.157, y sigue abierto a 4 de octubre de 2026. A las versiones antiguas les faltan más de estas correcciones.
5. Para desarrolladores: prevenirlo en tu propia app (API/SDK)
Si construyes una app que conectas tú mismo a la API/SDK de Claude (extended thinking + tool use), te toparás con el mismo error en tu propia implementación. La documentación oficial resume la prevención en una sola regla: devolver cada turno del asistente exactamente como lo devolvió la API, con sus bloques de thinking, y solo añadir mensajes nuevos al final.
// BAD 1: rebuilding the assistant message from picked block types
const rebuilt = {
role: 'assistant',
content: [
...response.content.filter(b => b.type === 'thinking'), // drops redacted_thinking
...response.content.filter(b => b.type === 'tool_use'),
],
};
// BAD 2: deleting thinking blocks that have empty text and only a signature
// On newer models this is the normal shape (display defaults to "omitted")
// GOOD: push the assistant message from the API untouched, then append
messages.push({ role: 'assistant', content: response.content }); // thinking, redacted_thinking and signatures included
messages.push({ role: 'user', content: [toolResult] }); // new messages go at the end only
① Un bloque de thinking con el texto vacío y solo la signature es normal. En los modelos más nuevos, display tiene "omitted" por defecto: el razonamiento completo va cifrado dentro de signature y el campo thinking llega vacío. Devuélvelo tal cual, sin rellenarlo ni eliminarlo (el texto que pongas en el campo thinking de un bloque omitido se ignora).
② No recortes tú mismo el thinking de turnos pasados. Si devuelves todos los bloques, la API conserva los que necesita cada modelo, descarta el resto automáticamente y solo factura como entrada los bloques que realmente se muestran a Claude. Fuera del uso de herramientas se permite omitir el thinking de turnos anteriores, pero en los modelos más nuevos un bloque de thinking solo es válido mientras el prompt system, las tools y los mensajes anteriores no cambien: editar un turno intermedio o eliminar solo algunos bloques invalida todos los bloques de thinking posteriores y devuelve un 400 (Invalid signature in thinking block; se aplica, por ejemplo, a las cuentas creadas a partir del 31 de agosto de 2026). Para aligerar el historial, déjalo en manos de la edición de contexto del servidor (borrado de bloques de thinking) o de la compactación.
③ Trata igual los bloques redacted_thinking. Un filtro que conserva o elimina solo type === 'thinking' pierde los redacted_thinking sin avisar. La guía oficial de solución de problemas señala como causas más frecuentes de este error filtrar los bloques por tipo y perder los redacted_thinking, y reconstruir el mensaje del asistente en lugar de devolverlo tal cual (Thinking, Thinking troubleshooting, a 4 de octubre de 2026).
La regla de oro para los bucles de tool-use
En los bucles de extended thinking + tool use (tool_use → tool_result), nunca alteres el bloque de thinking del "último" mensaje del asistente. La siguiente petición que devuelve tool_result debe incluir el thinking + tool_use precedentes exactamente tal cual. Si usas el Claude Agent SDK o el Vercel AI SDK, verifica que la librería lo gestiona correctamente.
6. Cómo distinguirlo de errores parecidos
Hay varios errores 400 relacionados con thinking, fáciles de confundir. Distingue los tres principales.
| Mensaje de error | Significado | Solución principal |
|---|---|---|
| thinking blocks ... cannot be modified | El tema de este artículo. La signature y el contenido no coinciden | /rewind, sesión nueva, actualizar a la última versión |
| Invalid signature in thinking block | Falla la verificación de la signature: el bloque thinking se alteró o dañó tras la respuesta original (al reconstruir el historial o porque un proxy reescribió el contenido) | /rewind, nueva sesión, actualizar a la última versión; si usas un proxy, revisa también su configuración |
| The final block in an assistant message cannot be thinking | El mensaje del asistente termina en thinking (necesita text o tool_use al final) | Corregir la estructura del mensaje, actualizar el SDK |
La causa raíz compartida es "no manejar correctamente los bloques de extended thinking". Para los usuarios de Claude Code, la mayoría se resuelve con /rewind + actualización a la última versión. Para apps caseras, hay que revisar la estructura de los mensajes y la implementación de la librería. Si pasas por un proxy (CLIProxyAPI, varios gateways), sospecha primero que el proxy está alterando el thinking.
7. Checklist para evitar que se repita
Un checklist práctico para evitar que se repita con frecuencia.
Usuarios de Claude Code: ① Mantenlo en la última versión con claude update (la mayor medida preventiva). ② Reinicia periódicamente las sesiones muy largas con /clear (reduce el riesgo de entremezclado). ③ Haz commit a git con frecuencia en el trabajo importante (recuperable aunque se atasque). ④ Considera una herramienta de reparación de JSONL si se repite mucho. ⑤ Reporta las reproducciones en los issues oficiales de Anthropic (acelera las correcciones).
Desarrolladores de API/SDK: ① Inserta los mensajes del asistente en el historial sin alterar la respuesta de la API (con thinking, redacted_thinking y signature). ② Mantén el historial solo con añadidos al final: no edites turnos intermedios ni elimines solo algunos bloques (deja el recorte a la edición de contexto del servidor o a la compactación). ③ No elimines los bloques de thinking con texto vacío y signature (es la forma por defecto en los modelos más nuevos). ④ Usa el último SDK oficial y minimiza el remodelado personalizado de mensajes. ⑤ Si estás detrás de un proxy, verifica la transparencia del thinking.
Resumen
El error 400 "thinking blocks ... cannot be modified" de Claude Code ocurre cuando los bloques de extended thinking se corrompen al reenviar el historial y dejan de coincidir con la respuesta original. Es un bug conocido con varios issues en el repo oficial de Anthropic, y en la mayoría de los casos no es culpa tuya. Las cinco causas: bug al reanudar sesión / reconstruir el historial, entremezclado de streaming, lógica de reparación descontrolada, proxies de terceros y modificación del historial en tu propia app.
Para los usuarios de Claude Code, la recuperación más rápida es ① pulsar Esc×2 / /rewind hasta un checkpoint; si falla, ② una sesión nueva (/clear); para preservar el contexto, ③ una herramienta de reparación de JSONL. La solución permanente más importante es "actualizar Claude Code a la última versión" — el changelog recoge una corrección tras otra para esta familia. Los desarrolladores de API/SDK deben devolver cada turno del asistente tal cual, con sus bloques de thinking / mantener el historial solo con añadidos al final / no eliminar los bloques con texto vacío y signature.
Relacionado: Qué es el Claude Agent SDK, guía completa del Vercel AI SDK, Qué es Cursor, flujo de despliegue con Claude Code/Cursor.
FAQ
Q. ¿Este error es un fallo de mi prompt o de mi código?
A. En la mayoría de los casos, no. Si aparece durante el uso de Claude Code, es casi con seguridad un bug conocido del lado de Claude Code (un defecto al reconstruir el historial de la sesión). Hay varios issues abiertos en el repo oficial de Anthropic y las correcciones están en marcha. No hace falta culparse. Solo en apps caseras (que conectan directamente con la API) hay que revisar la implementación.
Q. /rewind no lo arregla. ¿Y ahora qué?
A. Iniciar una sesión nueva (/clear) es lo más fiable. Pierdes el contexto, pero sales del estado atascado con seguridad. Guarda primero el trabajo importante mediante git commit o notas. Si se repite, actualiza Claude Code a la última versión; si sigue ocurriendo, considera una herramienta de reparación de JSONL.
Q. ¿Puedo evitarlo desactivando extended thinking?
A. Técnicamente sí, pero extended thinking mejora notablemente la precisión en tareas complejas, así que desactivarlo no es recomendable. Primero atájalo con actualización a la última versión + /rewind, y considéralo solo como último recurso en entornos especiales (por ejemplo, detrás de un proxy) donde aún se repita.
Q. ¿Es segura la herramienta de reparación de JSONL?
A. Es no oficial, así que úsala bajo tu propia responsabilidad. Haz siempre una copia de seguridad del JSONL de la sesión antes de usarla. El mecanismo es "eliminar todos los bloques de contenido de thinking conservando el historial de conversación", lo cual es seguro en principio — pero la corrección oficial (actualizar a la última versión) sigue siendo la solución real.
Q. En mi propia app, combinar tool use con thinking dispara este error.
A. La causa es "que estás alterando el bloque de thinking del último mensaje del asistente". La siguiente petición que devuelve tool_result debe incluir los bloques de thinking + tool_use precedentes exactamente como los devolvió la API (con la signature). No hace falta que recortes tú el thinking de turnos pasados; en los modelos más nuevos, quitarlo solo de algunos turnos invalida los bloques de thinking posteriores. Un bloque con el texto vacío y solo la signature es la forma normal en esos modelos, así que devuélvelo sin cambios. El último SDK oficial gestiona la mayor parte de esto automáticamente.
Errores de Claude Code relacionados: referencia de errores de Claude Code, el error "court" e invoke, "Prompt is too long".
Relacionado: El pensamiento adaptativo de Claude.