Claude Code «Error writing file»: mira la causa real con Ctrl+O
«Error writing file» en Claude Code es solo una etiqueta: con Ctrl+O ves el mensaje real (EACCES, modified since read, content is missing) y su arreglo.
En esta página

Error writing file no es el error, sino la línea corta que Claude Code pone en rojo bajo Write(ruta) cuando la herramienta de escritura falla. El motivo completo llega a Claude como resultado de la herramienta, y tú lo ves en la vista de transcripción, que en la terminal se abre con Ctrl+O. Con ese texto delante sabes qué tipo de arreglo toca: cambiar el entorno (permisos del directorio, privacidad de macOS, ruta, codificación), cambiar cómo escribe Claude (volver a leer, escribir por partes) o tratarlo como un fallo conocido en el que el archivo ya está bien escrito.
Los mensajes marcados como reproducidos salen de pruebas hechas el 16 de octubre de 2026 con Claude Code 2.1.295 (app de escritorio, macOS, Opus 5.5). Ese día la versión publicada en npm era la 2.1.301. Windows, los recortes por límite de tokens y los fallos de rutas relativas y de plan mode no se reprodujeron; para esos casos se citan los informes de GitHub con su número y versión.
Cómo ver el mensaje real de «Error writing file» con Ctrl+O
En la vista normal de la conversación solo aparece esto, a veces varias veces seguidas:
● Write(app/Mcp/Tools/GetMyTasksTool.php)
⎿ Error writing filePulsa Ctrl+O. Se abre la vista de transcripción (transcript viewer), que según los atajos del modo interactivo de Claude Code muestra el uso detallado de cada herramienta. Ahí está el texto que recibió Claude, por ejemplo File has been modified since read… o EACCES: permission denied…. Sales con q, Esc o Ctrl+C. La documentación avisa de que algunos atajos cambian según la terminal y la plataforma.
La página de errores de la documentación de Claude Code describe este mismo patrón para las ediciones bloqueadas: la conversación enseña solo Error editing file y el mensaje completo queda en la vista de transcripción. Esa página no tiene ninguna entrada para la cadena Error writing file, así que hay que buscar el texto de detrás.
Si usas la app de escritorio, el resultado de la llamada a Write muestra ese texto al abrirla. En cualquier superficie, incluida la extensión de VS Code o JetBrains, puedes pedirle a Claude que copie literalmente el error que le devolvió la herramienta: él recibe el mensaje entero aunque tú veas solo la línea roja.
Antes de arreglar nada, comprueba si el archivo ya está en disco. Hay falsas alarmas conocidas, y a veces Claude acaba escribiendo el archivo con Bash o con python -c después de varios fallos:
git status --short
git diff -- ruta/del/archivo
ls -l ruta/del/archivo
tail -n 20 ruta/del/archivoSi el contenido es el esperado, no hay nada que reparar en ese archivo.
Tabla de diagnóstico: mensaje real de Write, causa y arreglo
| Mensaje en la vista de transcripción | Causa | Qué haces | Base |
|---|---|---|---|
File has been modified since read, either by the user or by a linter. Read it again before attempting to write it. | Algo cambió el archivo después de que Claude lo leyera: el editor, un formateador, un hook, un watcher | Que Claude lo vuelva a leer. Si se repite en bucle, para lo que lo está tocando | Reproducido en 2.1.295 |
EACCES: permission denied, open '…/new.txt.tmp.35734.7a96eba60d51' | El directorio no admite escritura para tu usuario | Devuelve el permiso de escritura al directorio, no al archivo | Reproducido en 2.1.295 |
EPERM: operation not permitted en Escritorio, Documentos, Descargas o iCloud Drive | La privacidad de macOS bloquea la app de terminal | Ajustes del Sistema, Privacidad y seguridad, Archivos y carpetas | Documentación |
…/isdir is a directory, not a file. To create a file inside it, include the file name in file_path. | La ruta apunta a una carpeta | Pide la ruta completa con el nombre del archivo | Reproducido en 2.1.295 |
File is not valid UTF-8. It may use a legacy encoding such as Windows-1252, Shift-JIS or GBK, or be binary | El archivo no está en UTF-8 | Decide antes si conviertes a UTF-8 o editas con un comando que conserve la codificación | Documentación |
InputValidationError: Write failed … con file_path o content missing | La llamada llegó sin parámetros, casi siempre porque la respuesta se cortó | Esqueleto primero y luego partes pequeñas | GitHub #895, abierto |
API Error: Claude's response exceeded the … output token maximum justo antes | La respuesta superó el límite de salida | Escribir por partes, o responder continue | Documentación, GitHub #7927 |
Refusing to write …: it is a symbolic link. Write to the link's target path instead | La ruta es un enlace simbólico | Escribir en la ruta real del destino | Documentación |
This write was blocked because the path is spelled in a form that cannot be safely resolved… | Sesión aislada en worktree y ruta con symlink, ruta de red o directorio ilegible | Normalmente nada: Claude reintenta con la ruta directa | Documentación |
ENOSPC o EDQUOT sobre el directorio temporal de Claude Code | Disco o cuota llenos | Liberar espacio | Documentación |
Command failed: cygpath -u '…' en Windows con Git Bash | Fallo de conversión de rutas en MINGW64 | Ver la sección de Windows | GitHub #25971 |
| Ningún detalle útil y el archivo está bien | Falsa alarma conocida | Ignorarla y decirle a Claude que no reescriba | GitHub #29841, #24151 |
Dos ideas cambian el diagnóstico. Primero, una carpeta padre que falta no es la causa: en la prueba, Write a newparent/sub/file.txt sin que existiera ninguna de las dos carpetas terminó con File created successfully. Segundo, no haber leído antes el archivo tampoco explica siempre el fallo: con los modelos nuevos, Write puede sobrescribir un archivo existente sin leerlo, como se detalla en la sección de «Error editing file».

«File has been modified since read»: algo tocó el archivo después de leerlo
Este mensaje significa que el archivo cambió en disco entre la lectura de Claude y su intento de escribir. Write lo rechaza para no pisar cambios que Claude no ha visto. En la prueba bastó con leer el archivo, modificarlo desde Bash con un echo y lanzar Write para obtener el mensaje exacto.
El cambio no tiene que ser tuyo. En el issue #10498 de Claude Code en GitHub, un usuario de macOS describe que abrir o previsualizar el archivo en el IDE bastaba para provocarlo aunque el contenido no cambiara. Otros informes de Windows, WSL y del editor de Unity (#11463, #8750, #13207) hablan de bucles con la versión antigua del mensaje, File has been unexpectedly modified. Read it again before attempting to write it., y en el #10245 un archivo bloqueado por otro proceso producía ese mismo texto, que no describe la causa real. Esos informes son de 2025, con versiones 2.0.x.
Qué hacer:
- Deja que Claude vuelva a leer el archivo una vez. Es lo que pide el mensaje y suele bastar.
- Si el mismo mensaje vuelve en el mismo archivo una y otra vez, busca qué lo está reescribiendo: «formatear al guardar» en el editor, un servidor de desarrollo o un watcher que regenera archivos, una herramienta como Unity que reimporta, o un hook de Claude Code que formatea tras cada escritura. Cierra ese archivo en el editor o pausa el proceso mientras Claude trabaja.
- Si el formateador es un hook
PostToolUse, el archivo cambia justo después de cada escritura y una relectura antes de la siguiente es lo esperado. Cómo se configuran esos hooks está en Claude Code: hooks, comandos de barra y skills, ¿cuál usar?. - Para cambios parciales, pide Edit en lugar de Write. Desde la versión 2.1.208, Edit puede aplicar un cambio sobre un archivo modificado si
old_stringcoincide exactamente con el contenido actual, mientras que Write en 2.1.295 sigue exigiendo una lectura reciente.
EACCES y chmod 444: lo que bloquea Write es el directorio
Write no abre el archivo de destino y lo sobrescribe en el sitio. Guarda primero un archivo temporal al lado, con un nombre del tipo new.txt.tmp.35734.7a96eba60d51, y luego lo renombra. Por eso el mensaje de permisos nombra un archivo .tmp que tú nunca creaste:
EACCES: permission denied, open '…/rodir/new.txt.tmp.35734.7a96eba60d51'Ese resultado salió de escribir dentro de un directorio con modo 555. La consecuencia contraintuitiva es la otra prueba: un archivo con chmod 444 dentro de un directorio con permiso de escritura sí se sobrescribió. El contenido cambió y el modo siguió siendo -r--r--r--. Los permisos del archivo no lo protegen de Write; los del directorio, sí.

Qué hacer con EACCES:
- Mira el propietario y los permisos de la carpeta, no solo del archivo:
ls -ld ruta/de/la/carpeta. - Si la carpeta pertenece a otro usuario (por ejemplo, la creó un comando con
sudo), devuelve la propiedad o el permiso de escritura a tu usuario. No apruebes que Claude escriba consudopara salir del paso. - Si lo que quieres es que Claude no toque un archivo,
chmod 444no sirve. Usa una regla deny de permisos. Según las reglas de Edit y Write en la referencia de herramientas de Claude Code, una regla deny deReadsobre una ruta también bloquea Edit y Write en ella, incluso para crear un archivo nuevo (desde la versión 2.1.208 en ediciones y desde la 2.1.228 en escrituras). Los modos de permisos y lo que sigue bloqueando una llamada aunque los saltes están en Claude Code --dangerously-skip-permissions: comando, ajustes y alternativas.
EPERM en Escritorio, Documentos o Descargas en macOS
En macOS, EPERM en ~/Desktop, ~/Documents, ~/Downloads o iCloud Drive suele significar que el sistema bloquea a tu app de terminal en esa carpeta; un ls ahí devuelve Operation not permitted incluso con sudo. La documentación lo describe al leer el directorio de trabajo; como el bloqueo lo pone el sistema y no Claude Code, cabe esperar lo mismo al escribir. Cierra la terminal con Cmd+Q y vuelve a abrirla. Si sigue fallando, activa esa carpeta para tu terminal en Ajustes del Sistema > Privacidad y seguridad > Archivos y carpetas y reinicia la terminal.
Archivos grandes: «content is missing» y respuestas cortadas
Cuando el detalle es este, el problema no está en el disco:
InputValidationError: Write failed due to the following issue: The required parameter `content` is missingLa llamada a Write llegó sin content, sin file_path o sin ambos. El issue #895 de Claude Code en GitHub sigue abierto y reúne casos con archivos grandes, sesiones largas y subagentes; hay duplicados en #47189 (subagentes, abril de 2026), #21159 (versiones 2.1.19 y 2.1.20) y #51962 (versión 2.1.117). En el #7927, un usuario vio Error writing file justo después de API Error: Claude's response exceeded the 32000 output token maximum mientras generaba scripts de prueba grandes.
La documentación de errores explica el límite de salida: si una respuesta en streaming falla, Claude Code la reenvía sin streaming y esa respuesta se corta en 64.000 tokens de salida, un tope que la variable CLAUDE_CODE_MAX_OUTPUT_TOKENS no puede subir. Antes de la versión 2.1.299, una respuesta cortada así terminaba el turno sin ningún aviso.
Muchos de los informes vienen de sesiones con gateways o modelos de terceros. En el #895, un usuario que trabajaba con la extensión de VS Code a través de un proxy LiteLLM hacia la API de GitHub Copilot rastreó la cadena: el streaming fallaba, Claude Code pasaba a una petición sin streaming con un tope de 16.000 tokens y la llamada a la herramienta se cortaba a mitad de parámetro. Es el análisis de ese usuario, no algo que Anthropic haya confirmado. Otro comentario cuenta que, al cambiar de GLM 4.5 a GLM 4.7, todas las llamadas a herramientas empezaron a llegar con los parámetros vacíos. Si solo falla a través de un gateway, revisa esa ruta con Configuración de Claude Code API: claves, settings.json, modelos y gateways o, si usas OpenRouter o DeepSeek, con Claude Code con OpenRouter y DeepSeek: rutas, configuración y primeros errores.
Lo que más usuarios confirman que funciona es dividir la escritura:
- Interrumpe con
Escen cuanto el mismoInputValidationErrorse repita. Reintentar el mismo Write completo produce la misma llamada demasiado larga. - Pide un esqueleto del archivo de unas 100 líneas y luego que lo complete con Edit en partes de 100–200 líneas.
- Para que sea la norma del proyecto, añade a
CLAUDE.mduna línea como «Escribe los archivos grandes por partes: primero un esqueleto y luego secciones de 100–200 líneas con Edit». - Si la respuesta se cortó tras escribir algo de texto, responde
continue. La recomendación oficial es pedir la salida en partes, «one file or one section per reply». - Actualiza a la versión 2.1.299 o posterior con
claude update, para que un corte por límite de salida muestre su mensaje en lugar de terminar el turno en silencio.
Falsas alarmas: «Error writing file» con el archivo ya escrito
Hay dos casos documentados en GitHub en los que la línea roja aparece aunque la escritura funcione:
- Rutas relativas, versión 2.1.63 en macOS. En el issue #29841 de Claude Code en GitHub, cada Write con una ruta relativa como
app/Mcp/Tools/GetMyTasksTool.phpmostrabaError writing file, y todos los archivos estaban creados con el contenido correcto. Se cerró por inactividad el 29 de marzo de 2026 sin que conste un arreglo. - Primera escritura en plan mode, versiones 2.1.37 a 2.1.50. En el issue #24151 de Claude Code en GitHub, la primera escritura del archivo del plan fallaba siempre y el reintento automático funcionaba. Se reportó en WSL2 con la 2.1.37 y se confirmó en macOS, en Ubuntu con la 2.1.42 y en Manjaro con la 2.1.50; la última versión sin el fallo era la 2.1.29. También se cerró por inactividad, el 5 de abril de 2026.
Ninguno de los dos informes dice si el fallo está corregido. Si ves el error con un archivo que en disco está bien, la respuesta práctica es la misma: comprueba el contenido con git diff o tail, dile a Claude que el archivo ya está escrito para que no lo rehaga, y actualiza con claude update.
Windows con Git Bash: comillas, barras invertidas y cygpath
En Windows hay dos informes distintos, ninguno reproducido aquí por falta de una máquina con Windows:
- En el issue #63838 de Claude Code en GitHub (con #63836 y #63837), en Windows 10 con Git Bash, Write y Edit fallaban con
Error writing fileyError editing filecuando el contenido llevaba comillas simples, barras invertidas o secuencias como</. Tras varios intentos, el modelo escribía el archivo conpython -co con un heredoc. Se cerró por inactividad en julio de 2026. - En el #25971, en MINGW64, todas las escrituras y comandos de Bash fallaban con
Command failed: cygpath -u 'C:\Users\HIPOLI~1\AppData\Local\Temp', una ruta temporal con nombre corto de estilo 8.3. Se cerró como duplicado.
Si Claude acaba escribiendo con python -c o un heredoc, el archivo puede quedar bien, pero revísalo: es justo el contenido con comillas y barras invertidas el que más fácil se rompe al pasar por la shell. Si lo que ves es el error de cygpath, ningún informe documenta un arreglo; actualiza y comprueba si sigue apareciendo.
«Error editing file»: el texto que Edit busca no coincide
Error editing file es la misma etiqueta corta para la herramienta Edit, y el detalle también está en Ctrl+O. Edit sustituye un texto exacto (old_string) por otro, sin expresiones regulares ni coincidencias aproximadas, así que estas son las causas habituales:
- El texto no coincide. Un solo espacio o un nivel de sangría distinto basta para que no lo encuentre. El detalle, reproducido en 2.1.295, es
String to replace not found in file.seguido del texto buscado. Que Claude vuelva a leer el archivo y copie el fragmento tal como está. - El texto aparece más de una vez. Edit exige una coincidencia única, salvo que use
replace_all. En 2.1.295 el detalle fueFound 2 matches of the string to replace, but replace_all is false…. La solución es un fragmento más largo con contexto suficiente. - El archivo no está en UTF-8. Edit rechaza los archivos en Windows-1252, Shift-JIS, GBK o binarios y no los toca. Ese rechazo es reciente: según la entrada «File is not valid UTF-8» de la página de errores de Claude Code, antes de la versión 2.1.296 Edit y NotebookEdit aplicaban el cambio y guardaban cada byte que no podían decodificar como
U+FFFD, así que estropeaban el archivo sin avisar. Si tienes una versión anterior, actualiza Claude Code conclaude update. Ojo también con la salida fácil: Write sí puede sobrescribirlos, pero los guarda en UTF-8 y la codificación original se pierde. Decide tú si conviertes el archivo o si Claude debe editarlo con un comando que conserve la codificación. - Sesión aislada en un worktree. Si la ruta pasa por un symlink cuyo destino contiene
.., la edición se bloquea; Claude suele reintentar solo con la ruta directa. Si se repite en el mismo archivo, pídele que edite el archivo real, no el enlace.
Lo de leer antes de editar o escribir depende del modelo. Según la referencia de herramientas de Claude Code sobre Write, Opus 4.6, Haiku 4.5 y los modelos anteriores siempre necesitan una lectura previa del archivo existente. Desde la versión 2.1.228, los modelos más nuevos pueden sobrescribir un archivo no leído si leerlo no requeriría una petición de permiso y la herramienta Read está disponible. Los notebooks de Jupyter y los archivos leídos solo en parte con el aviso PARTIAL view requieren la lectura en cualquier modelo. En la prueba con Opus 5.5, un Write a un archivo existente nunca leído en la sesión funcionó sin error.
Cuándo cortar los reintentos de Claude Code
Claude corrige solo la mayoría de los errores de herramientas, y muchas veces el segundo intento basta. Interrumpe con Esc cuando el reintento no puede cambiar el resultado:
- El archivo ya está bien en disco. Es una falsa alarma; otro intento solo gasta tokens o lo reescribe por Bash.
- El mismo
InputValidationErrordos veces seguidas. La llamada vuelve a salir demasiado larga; pide la escritura por partes. EACCESoEPERM. Claude no puede arreglar los permisos del directorio ni la privacidad de macOS reintentando; lo cambias tú.File has been modified since readen bucle. Mientras el editor o el watcher siga tocando el archivo, cada relectura caduca enseguida.- Todas las herramientas fallan con parámetros vacíos. Si pasa con un modelo de terceros o a través de un gateway, el problema está en esa ruta y no en el archivo.
- Claude propone escribir con
sudoo convertir la codificación por su cuenta. Ahí la decisión es tuya.
Si lo que se cae no es una herramienta sino el proceso completo de Claude Code, es otro problema: Claude Code process exited with code 1: diagnostica la rama antes de reinstalar.
Qué se reprodujo con Claude Code 2.1.295 y qué no
Estas siete llamadas a Write se hicieron el 16 de octubre de 2026 en la app de escritorio de Claude Code 2.1.295, en macOS, con Opus 5.5 y el modo de permisos bypass. Son el texto que recibe Claude, el mismo que aparece en la vista de transcripción.
| Caso | Resultado |
|---|---|
Escribir un archivo nuevo dentro de un directorio con modo 555 | EACCES: permission denied, sobre el archivo temporal .tmp |
Sobrescribir un archivo con modo 444 en un directorio con permiso de escritura, tras leerlo | Funcionó; el modo siguió siendo -r--r--r-- |
| Write con una ruta que es un directorio | … is a directory, not a file |
| Leer, cambiar el archivo desde Bash y escribir | File has been modified since read… |
| Sobrescribir un archivo existente nunca leído en la sesión | Funcionó con Opus 5.5 |
| Leer solo 3 líneas de un archivo de 162 KB y escribir | Funcionó; una lectura con límite de líneas no dio el aviso PARTIAL view |
Escribir en newparent/sub/file.txt sin carpetas padre | File created successfully; las carpetas se crearon |
En el mismo entorno se hicieron además dos llamadas a Edit: con un old_string que no estaba en el archivo devolvió String to replace not found in file., y con uno que aparecía dos veces, Found 2 matches of the string to replace, but replace_all is false….
No se reprodujeron el recorte por límite de tokens, los fallos de Windows con Git Bash, la falsa alarma con rutas relativas ni el fallo de plan mode. Para esos casos, lo que se sabe sale de los informes de GitHub citados arriba y vale para las versiones que indican.
Preguntas frecuentes
¿Por qué Claude Code no crea los archivos que dice que ha creado?
Abre la vista de transcripción con Ctrl+O y busca el resultado de cada Write. Si pone InputValidationError con content is missing, la llamada llegó vacía y no se escribió nada; pide el archivo por partes. Si hay un EACCES o un EPERM, el directorio no admite escritura. Si el resultado fue correcto pero no ves el archivo, compara la ruta que figura en la vista de transcripción con la carpeta que tienes abierta en el editor.
¿Hay que crear la carpeta antes de que Claude Code escriba un archivo dentro?
No. En la prueba con Claude Code 2.1.295, Write creó newparent/sub/file.txt sin que existieran las carpetas padre. Si falla, la causa está en los permisos del directorio que ya existe, en una ruta que apunta a una carpeta o en una regla deny.
¿--dangerously-skip-permissions arregla «Error writing file»?
No en los casos de permisos. Ese modo salta las peticiones de aprobación de Claude Code, pero no cambia los permisos del sistema operativo ni la privacidad de macOS: un directorio sin escritura sigue dando EACCES y una carpeta bloqueada por macOS sigue dando EPERM. Las pruebas de la tabla anterior se hicieron precisamente en modo bypass.
¿«Error writing file» es un error de la API de Claude?
No directamente. Es un fallo de la herramienta local que escribe en disco, y los errores 4xx o 5xx de la API tienen sus propios mensajes. El único vínculo con la API es el caso de las respuestas cortadas: si la respuesta del modelo se corta por el límite de salida, la llamada a Write llega incompleta y falla con InputValidationError.
Fuentes8
Páginas externas que cita esta guía, en el orden en que aparecen. Última actualización: 16 oct 2026.
Fuentes8
Páginas externas que cita esta guía, en el orden en que aparecen. Última actualización: 16 oct 2026.
- 1.atajos del modo interactivo de Claude Codecode.claude.com/docs/en/interactive-mode
- 2.página de errores de la documentación de Claude Codecode.claude.com/docs/en/errors
- 3.issue #10498 de Claude Code en GitHubgithub.com/anthropics/claude-code/issues/10498
- 4.reglas de Edit y Write en la referencia de herramientas de Claude Codecode.claude.com/docs/en/tools-reference
- 5.issue #895 de Claude Code en GitHubgithub.com/anthropics/claude-code/issues/895
- 6.issue #29841 de Claude Code en GitHubgithub.com/anthropics/claude-code/issues/29841
- 7.issue #24151 de Claude Code en GitHubgithub.com/anthropics/claude-code/issues/24151
- 8.issue #63838 de Claude Code en GitHubgithub.com/anthropics/claude-code/issues/63838





