¿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.

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 valida la signature contra el contenido byte a byte. Cuando Claude Code reconstruye el historial con un bug — por ejemplo, vaciando el texto de thinking pero conservando la signature — la signature deja de coincidir y 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.

CLAUDE CODE · 400 ERROR

El panorama completo del error de thinking-block

— Si la "signature" no coincide, la API rechaza toda la conversación

SÍNTOMA
Sesión atascada
Cada entrada repite el mismo 400
CAUSA
Signature no coincide
Texto vacío + signature residual
SALIDA MÁS RÁPIDA
Esc×2 → /rewind
Retrocede antes de la corrupció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. Los bloques de thinking también deben enviarse, pero la signature se calcula sobre "el texto de thinking original completo" — así que si el texto cambia aunque sea en un carácter, la validación de la signature falla. Por seguridad, la API rechaza los bloques de thinking cuya signature no coincide. 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.

5 CAUSAS RAÍZ

Cinco causas raíz de que la signature no coincida

CAUSA 1 · Bug al reanudar sesión (la más común)
Claude Code vacía el texto de thinking a "" pero conserva la signature. Al reanudar envía "texto vacío + signature original" y falla la validación. El clásico Issue #63147.
CAUSA 2 · Entremezclado de streaming
En sesiones largas, respuestas de la API en paralelo o en secuencia rápida se entremezclan en el JSONL. Fragmentos de mensajes distintos se mezclan y se rompe el orden de los bloques.
CAUSA 3 · La lógica de reparación se descontrola
El proceso interno de reparación del historial de Claude Code reordena o altera los bloques de thinking. Una reparación bienintencionada acaba rompiendo la signature.
CAUSA 4 · Proxy/SDK de terceros
Los proxies de retransmisión (CLIProxyAPI, etc.) vuelven a serializar los mensajes y alteran el thinking. La causa principal de los errores "Invalid signature".
CAUSA 5 · Modificación del historial en tu propia app
En apps que tú mismo conectas a la API/SDK, borrar, resumir o reformatear los bloques de thinking a mitad del bucle de tool-use antes de reenviarlos. El error de implementación casero más común.

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.

3 SOLUCIONES

Tres soluciones por velocidad de recuperación

SOLUCIÓN 1 · /rewind (máxima prioridad)
Pulsa Esc dos veces, o ejecuta /rewind. Retrocede al checkpoint anterior al turno corrupto. La mejor jugada — se recupera preservando el contexto.
SOLUCIÓN 2 · Sesión nueva
/clear o inicia una sesión nueva. Lo más fiable, pero pierdes el contexto. Anota o haz commit del trabajo importante antes.
SOLUCIÓN 3 · Reparar el JSONL
Elimina todos los bloques de thinking del JSONL de la sesión. Una herramienta de la comunidad (abajo) quita solo el thinking conservando el historial de conversación. Jugada avanzada que preserva el contexto.

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. Anthropic está desplegando de forma progresiva una "protección defensiva que detecta los bloques de thinking con texto vacío más signature y los elimina antes de enviar" para esta serie de bugs (#10199, #12225, #63147, etc.). Las versiones antiguas lo sufren con más frecuencia.

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. Tres principios lo previenen.

// 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)

Los tres principios: ① Preserva por completo el texto de thinking firmado y haz el round-trip intacto. ② Si no vas a enviar el thinking de turnos pasados, elimina el bloque entero (texto vacío más signature es el peor caso). ③ Añade una protección defensiva al construir la petición que detecte los bloques de thinking con "texto vacío pero con signature" y los elimine.

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 errorSignificadoSolución principal
thinking blocks ... cannot be modifiedEl 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 blockLa propia signature es inválida (a menudo por alteración del proxy)Revisar la configuración del proxy, conectar directamente a la API
The final block in an assistant message cannot be thinkingEl 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. Si descartas thinking pasado, elimina el bloque entero (nada de texto vacío más signature). Añade una protección defensiva al construir la petición (detectar texto vacío más signature → eliminar). 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 la signature criptográfica deja de coincidir con el contenido. 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 (la más común), 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" — Anthropic está desplegando de forma progresiva una protección defensiva. Los desarrolladores de API/SDK deben seguir los tres principios: hacer round-trip de los bloques de thinking tal cual / eliminarlos por completo si los descartan / añadir una protección defensiva.

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). Si descartas el thinking de turnos pasados, elimina el bloque entero (nada de texto vacío más signature). El último SDK oficial gestiona la mayor parte de esto automáticamente.