Errores de permisos de Claude Code: qué significa cada mensaje
Qué significa cada mensaje de bloqueo de Claude Code (bash denied by auto mode, reglas deny, hooks) y el ajuste exacto que lo desbloquea.
Cuando Claude Code te bloquea una acción, hay tres capas que han podido hacerlo: una regla deny o ask tuya, el clasificador de auto mode, o un hook PreToolUse. El texto del mensaje dice cuál ha sido, y cada una se desbloquea en un sitio distinto. Aquí está cada mensaje con su arreglo.
bash denied by auto mode · [Data Exfiltration] · /permissions
Ese aviso lo emite el clasificador de auto mode, no una regla tuya. En auto mode, todo lo que no sea una lectura ni una edición dentro del directorio de trabajo pasa por un segundo modelo que decide si la acción es segura, y cuando dice que no, Claude Code muestra ese aviso junto a la caja de entrada [1]. Lo que va entre corchetes es la etiqueta de la regla del clasificador que casó, por ejemplo [Data Exfiltration] o [Production Deploy]. Debajo de la llamada verás además la línea Denied by auto mode classifier [1].
El aviso no incluye el comando. Para verlo, busca la llamada en la conversación y pulsa Ctrl+O si aparece plegada. Para revisar y reintentar, abre /permissions y entra en la pestaña Recently denied: la tecla r marca una acción para que Claude la vuelva a intentar al salir del diálogo [1].
Si lo que bloqueó es un destino al que vas a volver durante toda la tarea (tu registro de paquetes privado, un dominio interno, el host de tus repos), descríbelo en autoMode.environment:
{
"autoMode": {
"environment": [
"$defaults",
"Source control: github.example.com/acme-corp and all repos under it",
"Internal package registry: npm.example.com"
]
}
}
Ese bloque va en ~/.claude/settings.json, en los managed settings o tras --settings, nunca en el settings del proyecto: el clasificador no lo lee de ahí, para que un repositorio clonado no pueda concederse permisos a sí mismo [2]. Comprueba lo que de verdad se aplica con claude auto-mode config. Cómo describir bien tu infraestructura ahí dentro, y por qué el token "$defaults" no es decorativo, está en la guía de autoMode.environment.
Cuándo no deberías desbloquearlo: si el bloqueo apareció al empujar a un host que no es el tuyo, el clasificador está haciendo su trabajo. Añadir ese host a environment es declararlo de confianza para siempre, no solo para esta vez.
Cuando el mensaje nombra la herramienta y la regla
Si el aviso nombra la herramienta y, cuando la regla lleva especificador, también la regla que casó, el bloqueo viene de una regla deny tuya o de tu organización, evaluada antes de que el clasificador llegue a ver nada [3].
Aquí el error habitual no es el mensaje, es lo que haces después: añadir un allow más concreto. No sirve, porque las reglas se evalúan en orden deny, luego ask, luego allow, y la especificidad no cambia ese orden [3]. El arreglo es quitar o estrechar el deny, en el fichero donde esté; /permissions te enseña las reglas activas y de dónde vienen. Cómo se escriben esas reglas para que protejan lo que quieres está en la guía del modelo de permisos.
Si la regla viene de managed settings, no hay nada que puedas hacer desde tu lado: ningún nivel, ni siquiera los flags de la línea de comandos, sobreescribe una regla de permisos gestionada [3].
allowManagedPermissionRulesOnly: por qué tus reglas dejan de contar
Si has buscado este nombre es porque te lo has encontrado en un fichero de tu empresa o porque tus reglas allow dejaron de surtir efecto de un día para otro. Es una clave que solo pueden fijar los managed settings, y convierte a los managed settings en la única fuente de reglas de permisos [4]. Mientras está puesta, Claude Code descarta las reglas allow que vengan de un fichero de settings, de --allowedTools o de la aplicación anfitriona [4].
No es un ajuste que negocies en local. El arreglo es pedirle a quien administra la flota que añada la regla a la fuente gestionada, que en macOS es /Library/Application Support/ClaudeCode/managed-settings.json y en Linux o WSL /etc/claude-code/managed-settings.json [4].
useAutoModeDuringPlan: por qué en modo plan te ejecuta comandos sin preguntar
Con auto mode disponible y useAutoModeDuringPlan activo, que es como viene de fábrica, en modo plan el clasificador revisa los comandos de shell en lugar de preguntarte a ti: los que aprueba se ejecutan y los que rechaza se bloquean [5]. Si prefieres que modo plan te pregunte, ponlo a false:
{
"useAutoModeDuringPlan": false
}
Y aquí está el detalle que se lleva la tarde: el fichero importa. Claude Code honra el false desde cualquier fuente gestionada, desde --settings, desde ~/.claude/settings.json y desde .claude/settings.local.json, incluso cuando la fuente gestionada que gana dice true. Pero un false en .claude/settings.json se ignora [6]. Si lo has puesto en el settings compartido del repositorio, el nombre del campo es correcto y aun así no pasa nada.
Denied by preToolUse hook from "repo settings" (hook errored)
Este mensaje no lo emite Claude Code. Lo emite Copilot CLI, que lee los hooks de tu .claude/settings.json y los ejecuta con un contrato distinto [7]. En el reporte de este fallo, que es de Windows, los hooks se lanzan con PowerShell en vez de bash y la variable $CLAUDE_PROJECT_DIR queda vacía, así que un hook escrito para Claude Code revienta al arrancar; y como el fallo se trata como denegación, bloquea todas las llamadas a herramientas [7]. El log lo dice más claro que el aviso: preToolUse hook from "repo settings" execution failed (fail-closed).
Si te pasa esto, revisa dónde se está ejecutando el hook antes de tocar su código. Lanza el mismo comando a mano desde la raíz del proyecto: si ahí funciona, el problema es el shell o el directorio desde el que lo invocan.
En Claude Code el bloqueo por hook se ve como Execution stopped by PreToolUse hook, seguido de lo que el hook escribiera. Un hook que sale con código 2 corta la llamada antes de que se evalúen las reglas de permisos, así que bloquea aunque tengas un allow que la aprobaría [3]. Para descartar el hook en una sola ejecución, arranca con --settings '{"disableAllHooks": true}'; ponerlo solo en tu settings de usuario no basta, porque el settings del proyecto tiene más peso y puede devolverlo a false [3].
Cómo saber cuál de las tres capas te ha bloqueado
| Lo que ves | Quién te ha bloqueado | Dónde se arregla |
|---|---|---|
... denied by auto mode con una etiqueta entre corchetes, o Denied by auto mode classifier | El clasificador de auto mode | autoMode.environment o una regla allow, en ~/.claude/settings.json. También desde la pestaña Auto mode de /permissions |
Permission to use Bash has been denied. | Una regla deny | El fichero donde viva esa regla. Si es gestionada, tu administrador |
Execution stopped by PreToolUse hook | Un hook tuyo | El script del hook |
Cuando el mensaje habla de que el modelo del clasificador is temporarily unavailable, no hay nada que configurar: Claude Code bloqueó la llamada sin veredicto y esos casos ni siquiera se registran en Recently denied [1].
Si lo que quieres no es desbloquear un mensaje suelto sino dejar escrito de una vez qué puede hacer tu agente y qué no, la guía completa del modelo de permisos cubre la sintaxis de las reglas y en qué fichero va cada palanca, y la configuración de auto mode entra a fondo en autoMode.environment. Decidir dónde poner el límite de un agente antes de soltarlo es justo lo que se practica en el curso de Patrones de Diseño para Agentes de IA.
Fuentes
- Configure auto mode — Review denials — texto literal del aviso
bash denied by auto mode · [Data Exfiltration] · /permissions, la líneaDenied by auto mode classifier, la pestaña Recently denied y el caso del clasificador no disponible. - Configure auto mode — Where the classifier reads configuration — ámbitos que el clasificador lee, exclusión de los ficheros de proyecto, y el token
"$defaults". - Configure permissions — precedencia deny → ask → allow, mensaje
Permission to use ... has been denied., hooks con código de salida 2 y--settings '{"disableAllHooks": true}'. - Deploy managed settings — Managed-only settings —
allowManagedPermissionRulesOnly, qué fuentes descarta y las rutas del ficheromanaged-settings.jsonpor sistema. - Choose a permission mode — comportamiento de
useAutoModeDuringPlanen modo plan ypermissions.disableAutoMode. - Settings files and precedence — Exceptions to managed settings precedence — desde qué ficheros se honra un
falseenuseAutoModeDuringPlany cuál se ignora. - github/copilot-cli issue #4001 — mensaje
Denied by preToolUse hook from "repo settings" (hook errored)en Copilot CLI, con la traza del log y la causa.
Preguntas Frecuentes
¿Cómo desactivo auto mode del todo?
Poniendo permissions.disableAutoMode a "disable" en cualquier fichero de settings. Eso saca auto del ciclo de Shift+Tab y hace que una sesión arrancada con --permission-mode auto empiece en Manual. Una sesión que ya estuviera en auto mode sale de él cuando el ajuste le llega desde una fuente desplegada por el administrador, y muestra auto mode disabled by settings.
¿Por qué mi regla allow no funciona?
Porque hay un deny o un ask que casa con la misma llamada. Las reglas se evalúan en orden deny, luego ask, luego allow, y gana la primera que casa en ese orden, sin importar cuál es más específica. Un allow estrecho no abre una excepción dentro de un deny amplio.
¿Puedo saltarme una regla de permisos que ha puesto mi organización?
No. Los managed settings van por encima de todo lo demás y ningún nivel, incluidos los argumentos de la línea de comandos, sobreescribe una regla de permisos gestionada. Si además tu organización tiene puesto allowManagedPermissionRulesOnly, tus reglas allow se descartan directamente al leerlas.
¿Qué pasa si un hook falla?
Se trata como una denegación. Un hook PreToolUse que sale con código 2 corta la llamada antes de que se evalúen las reglas de permisos, así que el bloqueo se aplica aunque tengas una regla allow que la dejaría pasar. Un hook que ni siquiera arranca (ruta mal resuelta, shell equivocado) produce el mismo efecto con un mensaje mucho menos claro, y esa es la causa detrás del (hook errored) de Copilot CLI.
¿Los hooks pueden aprobar algo que una regla deny prohíbe?
No. Las decisiones de un hook no saltan las reglas de permisos: Claude Code evalúa deny y ask pase lo que pase, así que una regla deny que casa bloquea la llamada aunque el hook haya devuelto "allow", y una ask que casa te sigue preguntando. La precedencia funciona en un solo sentido: un hook puede bloquear de más, nunca de menos.