DEV Community

Cinco borrados reales hechos por agentes de IA este otoño y cómo prevenir cada uno

Este otoño se publicaron varios informes de agentes de programación (Claude Code, opencode y otros) que borraron cosas que no se podían recuperar. Los leí uno por uno.

Casi ninguno es un agente "que se volvió loco": son comandos normales que reciben una entrada distinta de la esperada. Por eso cada caso tiene una prevención concreta que sirve también cuando el comando lo escribe una persona.

1. Una variable vacía en rm -rf o rsync --delete

rm -rf "$BUILD_DIR" /*
rsync -a --delete src/ $R /

Si BUILD_DIR o R llegan vacíos, el primero se convierte en rm -rf /* y el segundo sincroniza contra la raíz. En anthropics/claude-code#109735 un rsync --delete en WSL terminó apuntando a /.

Prevención: "${BUILD_DIR:?}". Con :? la shell se detiene con un error si la variable está vacía o no existe, en lugar de seguir con una ruta truncada.

Un caso cercano es #95426:

rm -rf "$(cygpath -u 'C:\')"

como limpieza después de unas pruebas. cygpath devolvió /c/, la unidad entera, y la persona perdió unos 600 GB. Aquí :? no ayuda porque el valor no está vacío. Lo que sirve es guardar la ruta en una variable, imprimirla y comprobar que está dentro del proyecto antes de borrar.

Un caso parecido en PowerShell: Remove-Item -Recurse -Force (Split-Path $home) (anomalyco/opencode#62825). $home es una variable automática de PowerShell con la carpeta del usuario, así que Split-Path $home es la carpeta que contiene a todos los usuarios.

2. Espacios en rutas que pasan por xargs

find . -name '*.tmp' | xargs -n1 dirname | xargs rm -rf

xargs separa por espacios. Una ruta como ~/Library/Application Support/... se parte en dos y una de las mitades es ~/Library. Una publicación en r/ClaudeCode con unos 4.000 puntos contaba exactamente eso: se fue ~/Library entero.

Prevención: find ... -print0 | xargs -0, que separa por el carácter nulo y no por espacios.

3. rm -rf .git en un repositorio que ya existe

En #107274 el agente quería "empezar limpio" y borró .git en un repositorio con 12 meses de historial sin subir a ningún remoto.

Prevención: hacer push a menudo, aunque sea a una rama de respaldo, y no aceptar nunca un borrado de .git en un repositorio con commits.

4. Un enlace dentro de una carpeta que se borra

git worktree remove --force (o un borrado recursivo en PowerShell) sobre una carpeta que contiene una junction o un enlace simbólico a datos de fuera. En Windows algunas herramientas siguen el enlace y borran el destino. En r/ClaudeAI alguien perdió así unos 230 GB de modelos que estaban fuera del worktree.

Prevención: antes de borrar una carpeta temporal, buscar enlaces dentro (find . -type l, o dir /AL /S en Windows) y quitarlos primero.

5. pkill con un patrón demasiado amplio

pkill -f node o killall node para "reiniciar el servidor" también mata los servidores de otras sesiones y aplicaciones de escritorio hechas con Node. En macOS pkill -f cat coincide con todo lo que está bajo /Applications, porque "Applications" contiene "cat". Y en #109627, pkill ... --signal 0 en macOS no se interpretó como se esperaba y mandó SIGTERM a todas las demás sesiones de Claude Code abiertas.

Prevención: matar por PID. lsof -nP -iTCP:3000 -sTCP:LISTEN da el proceso que tiene el puerto, y kill <pid> lo cierra a él solo.

Lo que hice con esto

Mantengo un proyecto pequeño, claude-bulkhead, que convierte estos casos en hooks que se ejecutan antes de cada comando. Lee el comando que el agente va a lanzar, bloquea esta lista corta y le devuelve al agente el motivo y la forma segura. Normalmente el agente reescribe el comando y sigue.

Funciona como plugin de Claude Code y también con Codex, Gemini CLI, Copilot CLI, Cursor, opencode y otros. Es MIT, sin dependencias, Node 18 o superior.

Se puede probar sin instalar nada; este comando no ejecuta el comando que recibe, solo lo analiza:

npx -y claude-bulkhead explain -- 'rm -rf "$BUILD_DIR"/*'

La respuesta dice BLOCKED by basics rm-empty-var y propone rm -rf "${BUILD_DIR:?}"/*.

El límite importante: solo ve el texto del comando. Si el agente escribe un script y luego lo ejecuta, un borrado dentro del script no se detecta. Las prevenciones de arriba siguen siendo la primera defensa.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.