SpyBara
Go Premium

plugins/mods/troubleshoot.md 2026-10-21 23:02 UTC to 2026-10-22 22:58 UTC

This page contains 41 additions and 30 deletions.

2026
Thu 1 23:59 Fri 2 22:59 Tue 6 23:59 Thu 8 22:58 Fri 9 23:02 Sat 10 23:01 Thu 15 23:58 Fri 16 22:59 Mon 19 23:58 Tue 20 23:00 Thu 22 22:58 Fri 23 22:59 Sat 24 22:59 Sun 25 23:58 Mon 26 22:57 Tue 27 22:59 Wed 28 23:57

Solucionar problemas de un mod

Descubre por qué un mod de Claude Code no hace nada: relaciona el síntoma o mensaje con su causa, consulta los mensajes de rechazo y lee el registro de depuración.

Cuando el módulo de un mod o uno de sus hooks falla, Claude Code lo omite y la sesión continúa, por lo que un mod defectuoso puede parecer uno que no hace nada. Empieza por comprobar qué leyó Claude Code de tu mod y dónde informa de un problema; luego busca el síntoma o mensaje que tienes.

Averigua por qué un mod no hace nada

Cuando un mod no hace nada, revisa lo que Claude Code lee de los archivos del mod y la línea que escribe cuando omite algo. Para lo primero, en tu shell ejecuta claude plugin validate con el directorio del mod, como en claude plugin validate ./first-mod. Detecta un evento mal escrito, un manifiesto incorrecto y un módulo que Claude Code no puede leer, sin iniciar una sesión.

Cuando un módulo no se carga, se omite un hook u otro mod rechaza el tuyo, Claude Code escribe una línea que nombra tu mod. Dónde lees esa línea depende de la sesión:

  • Una sesión que recarga en caliente un directorio de plugin: una línea atenuada en la transcripción. Es una sesión interactiva que iniciaste con --plugin-dir, o una en la que habilitaste la recarga en caliente para los mods que escribió Claude.
  • Cualquier otra sesión interactiva, como una que ejecuta un mod que instalaste desde un marketplace: solo el registro de depuración. Para obtenerlo, inicia la sesión con claude --debug.
  • Una ejecución de claude -p con --plugin-dir: stderr, en el formato de salida de texto predeterminado. Un rechazo por parte de otro mod va solo al registro de depuración.

Comprobar si los mods pueden cargarse

Para comprobar si tu configuración permite que los mods se carguen, sin instalar ninguno, ejecuta claude plugin test en tu shell, desde un directorio que no contenga un mod. No necesitas una sesión. El mensaje que imprime te indica el estado:

El mensaje incluye Qué significa
no hooks module to load Los mods pueden cargarse. El comando no encontró ningún mod para probar en este directorio.
hooks modules are turned off here Un ajuste está bloqueando tus mods: disableAllHooks en tu propia configuración, o la política de tu organización
hooks modules are turned off in this process: the rollout switch served off Anthropic ha desactivado de forma remota los mods instalados.
hooks modules are turned off in this process: the rollout switch was saved off by an earlier session El comando usó un valor que guardó una sesión anterior, que puede estar desactualizado. Inicia claude una vez para actualizarlo y luego vuelve a ejecutar el comando.

Una organización también puede establecer allowManagedModsOnly para permitir solo sus propios mods, algo que este comando no informa. En ese caso, Claude Code rechaza un mod que instales, y un mensaje indica el motivo.

El mod no se carga

No aparece nada de lo que agrega el mod: ningún comando, ningún dibujo y ningún cambio de comportamiento.

Tu versión es demasiado antigua

Consulta qué versión usar y cómo comprobar la tuya.

La línea mods active no nombra el mod

No aparece nada de lo que agrega el mod, y la línea mods active en /plugin no lo nombra. El módulo de hooks no se cargó. Cuando Claude Code lo rechazó, el registro de depuración tiene una línea que empieza con hooks module, el nombre del mod y not loaded:, como en hooks module first-mod@inline not loaded: disableAllHooks in managed settings para un mod cargado con --plugin-dir.

Lee el motivo que aparece después de los dos puntos. La sección mensajes de rechazo enumera cada uno. Si el registro no tiene una línea así, revisa las demás entradas de este grupo.

Algunos ajustes detienen un mod y dejan funcionando el resto de su plugin. Activar o desactivar mods los nombra.

Una ejecución de claude -p muestra hooks module not loaded

La línea empieza con el nombre del mod y va a stderr. El módulo de hooks fue rechazado. Una ejecución no interactiva no tiene transcripción, así que el mensaje va a stderr.

Lee el motivo que aparece después de los dos puntos. La sección mensajes de rechazo enumera cada uno.

Mensajes de rechazo

Cada uno de estos aparece después de hooks module, el nombre del mod y not loaded: en el registro de depuración.

El mensaje empieza con Qué significa
hooks modules are turned off for installed plugins in this process: the rollout switch served off Anthropic desactivó de forma remota los mods instalados.
hooks modules are turned off for installed plugins in this process: the rollout switch was saved off by an earlier session La sesión usó un valor que guardó una sesión anterior, que puede estar desactualizado. Inicia Claude Code de nuevo para actualizarlo.
disableAllHooks in managed settings Tu organización desactivó los hooks de los plugins instalados
only managed plugins and built-in plugins run allowManagedHooksOnly está establecido, o disableAllHooks está establecido en un archivo de configuración distinto de la configuración administrada
installed plugins that are not managed load no hooks module in this mode (--bare) Iniciaste Claude Code con --bare
another plugin of that name loads first Otro plugin habilitado tiene el mismo nombre que tu mod y se queda con el nombre, así que tu módulo de hooks no se carga

Mensajes de la protección integrada

En una máquina con configuración administrada, o en una sesión cuya credencial es un /login de Team o Enterprise, la protección integrada puede rechazar un mod o una de sus respuestas. Cada mensaje nombra la opción que el administrador de tu organización establece para cambiar la regla.

El mensaje contiene Qué significa Dónde aparece
mods are limited to your organization's by policy (allowManagedModsOnly) Tu organización solo permite sus propios mods, así que el tuyo fue rechazado El registro de depuración, y la transcripción en una sesión que recarga en caliente un directorio de plugin
tried to lift a deny rule in your settings El hook tool.check de tu mod aprobó una llamada que una regla deny rechaza. La llamada sigue denegada. La transcripción y el registro de depuración, una vez por cada mod en una sesión. En una ejecución de claude -p, solo el registro de depuración.
the deny rules in your settings could not be checked for this call, so it is refused La protección falló al verificar una llamada que un mod aprobó, así que rechazó la llamada El motivo que Claude lee para la llamada denegada

validate pasa y no muestra ninguna línea hooks

hooks/hooks.json no tiene una clave modules, o la clave está mal escrita.

Agrega "modules": ["./register.js"].

hooks module did not load

La línea empieza con el nombre del mod, luego hooks module did not load: y un motivo, que indica el archivo y la línea cuando el problema está en tu código. Claude Code no pudo cargar el módulo, por ejemplo porque su código de nivel superior lanzó una excepción.

Corrige el error que indica el motivo.

Si el motivo termina con ; the version loaded before is unloaded, ninguna versión del mod se está ejecutando ahora. Una vez que corrijas el error, ejecuta /reload-plugins en la sesión para volver a cargar el mod. Si instalaste el mod y no lo escribiste tú, pídele a su autor que corrija el error.

options do not fit plugin.json userConfig

La línea empieza con el nombre del mod, luego hooks module did not load: options do not fit plugin.json userConfig: y un motivo. Una opción no pasa la validación contra su campo userConfig, como un número por encima del max del campo, o un campo obligatorio no tiene valor.

Establece o cambia el valor. El final de la línea nombra su entrada pluginConfigs en settings.json.

code nested too deep to scan: more than 2000 scopes

La línea empieza con el nombre del mod, luego hooks module did not load:, el archivo y code nested too deep to scan: more than 2000 scopes. Un archivo de un módulo de hooks no puede anidar alcances, como funciones, bloques y bucles, a más de 2000 niveles de profundidad. claude plugin validate informa el mismo motivo.

Reescribe el código para que sus alcances se aniden con menos profundidad.

the parser stopped o the engine ran out of stack loading the file

El código de un archivo del módulo de hooks está anidado con tanta profundidad que Claude Code se quedó sin pila al leerlo. La línea empieza con el nombre del mod y hooks module did not load:, y luego indica el nombre de ese archivo y uno de estos motivos:

  • code nested too deep to scan (the parser stopped: <message>)
  • the engine ran out of stack loading the file (code nested too deep): <message>

El motivo no indica ningún número de línea ni dice qué tipo de código está anidado, así que revisa tú mismo el archivo para encontrar su parte más profundamente anidada. Reescribe esa parte para que se anide menos. Si instalaste el mod y no lo escribiste tú, pídele a su autor que lo haga.

Ningún mod se carga en un directorio que abriste por primera vez

No respondiste la solicitud de confianza del directorio.

Inicia una sesión interactiva en ese directorio con claude y acepta la solicitud de confianza con la que se abre.

No se carga ningún plugin instalado

Iniciaste Claude Code con --safe-mode.

Inicia sin el flag.

Claude Code deja de preguntar si quieres habilitar la recarga en caliente

Claude escribe un mod en una sesión interactiva, no se carga nada y Claude Code no vuelve a preguntar si quieres habilitar la recarga en caliente. Si la pregunta termina tres veces sin que se elija una respuesta, la recarga en caliente permanece desactivada. Por ejemplo, la pregunta termina así cuando estableces askUserQuestionTimeout y el tiempo se agota antes de que respondas. Ese ajuste se aplica aquí porque Claude Code pregunta en el mismo cuadro de diálogo de preguntas que usa AskUserQuestion. Una pregunta que descartas tú mismo no cuenta para las tres.

Para ejecutar el mod, copia su directorio fuera de la carpeta de mods y luego, en tu shell, inicia una nueva sesión con --plugin-dir, como en claude --plugin-dir ~/mods/git-branch.

Un hook se omite o un mod se descarga

El mod se cargó y luego Claude Code omitió uno de sus hooks o lo descargó.

hook skipped

La línea nombra el mod y el evento, luego dice hook skipped: y un motivo, como en first-mod: tool.call hook skipped: threw Error: boom. Un hook lanzó una excepción, superó su límite de tiempo o devolvió un resultado con una forma incorrecta. La línea aparece una vez por cada evento y tipo de fallo hasta que el mod se recarga.

Corrige el error. El registro de depuración tiene una línea por cada ocurrencia.

no command.run hook answered it

Ejecutas un comando que agregó tu mod y la respuesta nombra el mod y el comando, como en first-mod registered /tally but no command.run hook answered it, y luego te indica que agregues un hook. Claude Code imprime esa respuesta cuando el comando llega al final de la cadena sin respuesta, lo cual ocurre en dos casos:

  • Ningún hook respondió al comando: el módulo no tiene un hook command.run, el filtro del hook nombra un comando diferente, o el hook devolvió next(e)
  • Claude Code omitió el hook: hook skipped enumera los motivos. Pasar focus: false a $.ui.open es una forma de llegar a esto.

Si el módulo ya tiene el hook que describe la respuesta, busca una línea hook skipped que nombre command.run, la cual indica el motivo. Una prueba que ejecuta el comando falla con el mismo motivo.

it crashed the hooks worker

La línea comienza con el nombre del mod, como en first-mod was unloaded: it crashed the hooks worker. Los mods instalados comparten un único hilo worker. El worker dejó de responder o falló, y Claude Code lo atribuyó a este mod y lo descargó. Un hook que bloquea el hilo, como un bucle que nunca usa await, es una de las causas.

Corrige el hook.

its session.start ran again in a fresh copy

La línea comienza con el nombre del mod y nombra una llamada a $.prompt.submit, $.command.run o $.agent.spawn, como en first-mod: its session.start ran again in a fresh copy; the $.prompt.submit call it had already made was not made again. Claude Code volvió a cargar el módulo del mod, por ejemplo después de que el hooks worker falló y fue reemplazado, y se ejecutó el hook session.start de la copia nueva. La llamada que nombra la línea se resolvió con el resultado de su primera ejecución en lugar de ejecutarse de nuevo, así que tu mod no envía el prompt, no ejecuta el comando ni inicia el subagente dos veces. El resto del hook se ejecutó como de costumbre.

No hay nada que corregir.

Antes de la v2.1.292, la llamada se ejecutaba una segunda vez, por lo que el prompt se enviaba, el comando se ejecutaba o el subagente se iniciaba dos veces.

$.agent.register refused: the hooks module that made the call is no longer loaded

La línea comienza con el nombre de tu mod, como en first-mod: $.agent.register refused: the hooks module that made the call is no longer loaded (it was reloaded or removed), y el agente no queda registrado. Tu mod se recargó o se descargó antes de la llamada. Una recarga carga una copia nueva del módulo de hooks, y esta llamada provino de código que aún se ejecutaba en la copia anterior, como un hook que aún no había retornado.

Si ese hook no captura el rechazo, falla y Claude Code lo omite. Para registrar el agente desde la copia que permanece cargada, haz la llamada en tu hook session.start, que se ejecuta de nuevo en cada copia nueva después de una recarga.

mods that run in the hooks worker are off for this session

La línea dice hooks: mods that run in the hooks worker are off for this session: it crashed 3 times. El worker se detuvo tres veces y Claude Code no pudo atribuir las detenciones a un solo mod, así que descargó todos los mods que no son integrados, incluidos los mods que instala tu organización. Esta línea llega a la transcripción en cada sesión interactiva.

Ejecuta /reload-plugins para cargarlos de nuevo.

Se deniega una llamada a herramienta

El mod se cargó y sus hooks se ejecutan, y una llamada a herramienta que tocó es rechazada.

a hook changed this call's input after the model wrote it

En modo automático, una llamada a herramienta denegada da este motivo. Un hook cambió la entrada de la llamada a herramienta después de que el clasificador del lado del servidor la revisara, por lo que esa revisión no cubre lo que se ejecutaría. El hook puede ser un hook tool.call o turn.step de un mod, o un hook de configuración PreToolUse. El mensaje no dice cuál.

El mensaje le indica a Claude que emita la llamada una vez más tal como quedó registrada. Si también se deniega, el hook cambia la entrada cada vez, así que desactiva el mod o el hook, o sal del modo automático y aprueba la llamada tú mismo.

Un mensaje sobre las reglas de denegación en tu configuración

tried to lift a deny rule in your settings y the deny rules in your settings could not be checked for this call, so it is refused provienen ambos de la protección integrada.

Búscalos en Mensajes de la protección integrada.

Aparece un aviso después de detener un turno

Stopped: type a message to continue; a mod cannot resume work after Stop

Este aviso significa que, después de que detuviste el turno, por ejemplo con Esc, un mod intentó iniciar trabajo por su cuenta y Claude Code no se lo permitió. No hay nada que corregir. Después de tu siguiente mensaje, los mods pueden volver a iniciar trabajo y parte de ese trabajo se reanuda por sí solo. Si lo que esperabas del mod no se reanuda, vuelve a pedirlo o ejecuta de nuevo el comando del mod.

Si tú escribiste el mod, consulta Llamadas y trabajo en segundo plano después de que el usuario interrumpe un turno.

Un dibujo no aparece o no responde

El mod se cargó, y su panel, banda, toast o controles no se comportan como esperas.

Se muestra la banda de otro mod y no la tuya

Hay una sola banda encima del prompt, y todos los mods la comparten. Un mod que se ejecuta antes que el tuyo reemplaza tu banda cuando devuelve un árbol que no incluye el resultado de next(e). Para mostrar ambas bandas, cambia el hook de ese mod, o pídele a su autor que lo haga:

  • Conservar las bandas posteriores: coloca el resultado de await next(e) entre los hijos de un Box en su árbol, como en la pestaña Banda encima del prompt de Elegir dónde dibujar
  • Mantener el árbol válido: no le des a ese Box, ni a ningún Box que lo rodee, una prop width, height, minWidth, minHeight, position, top, left, right, bottom, display u overflow

Para encontrar ese mod, escribe un registro de depuración y busca en él answered ui.render without next(). Una línea como other-mod (user) answered ui.render without next() nombra un mod que devolvió su árbol sin llamar a next(e). No nombra el punto de renderizado, así que también puede aparecer un mod que solo dibuja un panel. Un mod que llama a next(e) y descarta el resultado no genera ninguna línea, así que revisa también los hooks que se ejecutan antes del tuyo.

Después del cambio, no ves nada en la banda si alguno de los mods devuelve un árbol que no pasa la validación. Para leer el motivo, busca una línea ui.render (AbovePrompt) refused: en la transcripción de una sesión con --plugin-dir, o busca does not validate en el registro de depuración. Con varios mods en la banda, ninguna de las dos líneas nombra un mod, así que revisa el árbol de cada mod.

Un panel o una banda está vacío o muestra el contenido habitual de Claude Code

El árbol que devolvió tu hook no pasó la validación. Con --plugin-dir, la transcripción dice ui.render (Pane) refused: con el motivo, como en first-mod: ui.render (Pane) refused: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse; the engine drew its own. El registro de depuración tiene a hook returned a tree that does not validate con el mismo motivo.

Lee el motivo en esa línea. Las causas comunes son una prop que el elemento no acepta y un elemento que la app no tiene.

Una línea de ui.render dice threw while drawn

La línea nombra el punto de renderizado, luego dice threw while drawn: y el error, como en first-mod: ui.render (ToolUse) threw while drawn: <error>; the engine drew its own. Claude Code encontró ese error al dibujar el árbol que devolvió tu hook ui.render, o al dibujar el punto de renderizado a partir de las props que tu hook pasó a next. El final the engine drew its own significa que el punto de renderizado muestra el contenido habitual de Claude Code.

Lee el error y corrige el valor de tu hook que lo causó.

Antes de v2.1.289, este error en una fila de la transcripción terminaba la sesión con Claude Code exited after an unrecoverable interface error.

the module failed without a message

Un Client falló con un error que no tiene mensaje, como throw new Error(). La línea que aparece en su lugar se ve así: my-mod: Client client/spinner.js: the module failed without a message.

Busca el throw en el código de tu Client y dale un mensaje al error. Así, la línea muestra ese mensaje.

Antes de v2.1.289, la línea mostraba Error como motivo.

$.ui.open se ejecuta y no aparece ningún panel

La llamada no provino de algo que hizo el usuario, y la terminal es más estrecha que el ancho que necesita ese panel.

Abre el panel desde un comando o un botón, o revisa el resultado isPlaced de la llamada. Consulta Abrir un panel en el momento adecuado.

Un toast no aparece

Tu mod llama a $.ui.toast en una sesión interactiva de la terminal y no ves el toast. Para confirmar que la llamada se ejecutó, busca en el registro de depuración una línea con el nombre de tu mod y el texto del toast, como en $.ui.toast (first-mod): build finished. Luego revisa causas como estas:

  • Falta la línea de la llamada: busca una que diga por qué Claude Code rechazó la llamada, como en first-mod: $.ui.toast dropped: timeoutMs is a whole number of ms, 1 to 60000.
  • Un panel está reteniendo los toasts: tu mod u otro pasó holdToasts al abrir el panel que se está mostrando. Cierra el panel para terminar la retención. Si el panel es tuyo y debe permanecer abierto, quita holdToasts de su llamada a $.ui.open y vuelve a abrir el panel.
  • El toast está debajo del prompt: en el renderizador clásico, mira a la derecha, debajo del prompt. Un toast ahí es una línea que empieza con el nombre del mod, en lugar de un recuadro en la esquina superior derecha.
  • Tu mod lanzó un toast más reciente: en el renderizador clásico, un toast más reciente de tu mod puede ocupar el lugar de uno que se está mostrando o que espera para mostrarse. El registro de depuración tiene otra línea para el toast anterior, que termina con gave way, cut short si se estaba mostrando, o con gave way, unseen si nunca apareció. Para mostrar ambos mensajes, ponlos en un solo toast.
  • Al toast se le acabó el tiempo sin dibujarse: en el renderizado de pantalla completa, Claude Code dibuja como máximo tres toasts a la vez, así que a un toast se le puede acabar el tiempo antes de dibujarse. El registro de depuración tiene otra línea para ese toast, que termina con left the stack, never drawn. Cuando tu mod lance varios a la vez, pon los mensajes en un solo toast.

Antes de v2.1.290, Claude Code descartaba un toast lanzado dentro de los dos segundos posteriores al último que mostró para tu mod, y la línea del registro de depuración del toast descartado decía within 2000ms of the last; dropped.

Los atajos de teclado no hacen nada

Tu panel no tiene el foco del teclado, o el dibujo está en la extensión de VS Code, donde los botones no tienen atajos de teclado. Haz lo que corresponda:

  • Sin foco del teclado: presiona Ctrl+X y luego Tab, o haz clic en el panel. Para que el panel tome el foco al abrirse, ábrelo con focus: true desde un comando.
  • En la extensión de VS Code: haz clic en el botón, o presiona Enter sobre él cuando tenga el foco

Un dibujo funciona en la terminal y no en la app de escritorio ni en VS Code

O bien esa app no dibuja el punto de renderizado o el elemento, o bien la sesión es una en la que la extensión de VS Code no dibuja nada para los mods. Los demás hooks del mod se siguen ejecutando. Revisa estas causas:

  • El punto de renderizado o el elemento no se dibuja en esa app: busca tu punto de renderizado en la tabla de puntos de renderizado y tus elementos en la tabla de elementos. Para un elemento que la app no tiene, revisa e.surface en el hook y devuelve un árbol que la app pueda dibujar.
  • La extensión de VS Code es anterior a 2.1.299: el panel de chat dibuja para los mods a partir de la versión de la extensión 2.1.299. Revisa la versión en la vista Extensions de VS Code y actualiza la extensión ahí.
  • La extensión es anterior a 2.1.304 y la sesión no obtiene los feature flags: actualiza la extensión, o ejecuta claude en la terminal integrada de VS Code en su lugar. Las sesiones en Amazon Bedrock, Agent Platform de Google Cloud o Microsoft Foundry omiten la obtención. Para las demás que la omiten, como una sesión a través de un gateway de apps de Claude, consulta Funciones que necesitan obtener feature flags.

Se pierde una edición o un valor

El mod se ejecuta, y un cambio que hiciste o un valor que conservaba no está.

Tus ediciones no surten efecto

Estás editando un plugin que instalaste. Claude Code ejecuta la copia en caché de la versión instalada.

Desarrolla con --plugin-dir apuntando a tu copia de trabajo, como en claude --plugin-dir ./first-mod, que se recarga cuando guardas.

Un valor se restablece cuando el módulo se recarga

Las variables a nivel de módulo se reinicializan en cada recarga.

Guarda el valor en $.state o $.store.

Un valor se restablece después de /clear, /resume o /branch

Un valor se restablece, o un valor guardado se reemplaza por su valor predeterminado. Cada uno de esos comandos restablece $.state a sus valores predeterminados, y session.start no se vuelve a disparar.

Carga de nuevo el valor guardado en un hook classic.SessionStart.

Lee el registro de depuración

El registro de depuración tiene una línea por cada módulo que Claude Code carga o rechaza, cada hook que falla y cada resultado que rechaza, así que es donde debes buscar cuando la transcripción no muestra nada. Para generar uno, en tu shell inicia Claude Code con --debug, o con --debug-file <path> para elegir dónde se guarda:

claude --debug-file ./mod-debug.log --plugin-dir ./first-mod

En otra terminal, sigue el archivo y filtra por el nombre de tu mod:

tail -f ./mod-debug.log | grep first-mod

Un mod que se cargó tiene una línea que lo nombra y enumera los eventos que maneja. Un mod cargado con --plugin-dir aparece con su nombre seguido de @inline:

hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render

Un dibujo que no pasó la validación cuenta como un resultado rechazado y también recibe una línea. Para escribir tus propias líneas en el registro, llama a $.ui.log con un segundo argumento, como en $.ui.log('message', { to: 'debug' }). Sin el segundo argumento, $.ui.log agrega una línea atenuada a la transcripción.

Mientras editas un mod cargado con --plugin-dir, la transcripción muestra una línea por cada recarga que nombra el mod y enumera sus hooks. Si un guardado rompe el módulo, la línea dice reload failed, the previous version stays loaded: con el motivo, y la última versión que funcionaba sigue ejecutándose hasta que Claude Code vuelva a recargar los plugins, por ejemplo cuando ejecutas /reload-plugins.

Próximos pasos