mod 문제 해결 (Troubleshoot a mod)
기준일: 2026-11-03
공식 기준: Troubleshoot a mod
개요
mod의 module이나 hook 하나가 실패하면 Claude Code는 그것을 건너뛰고 세션을 계속합니다. 그래서 고장 난 mod는 아무것도 안 하는 mod처럼 보일 수 있습니다. 먼저 Claude Code가 mod에서 무엇을 읽었는지, 문제를 어디에 보고하는지 확인한 뒤, 겪는 증상이나 메시지를 아래에서 찾으세요.
핵심 개념
| 확인 수단 | 용도 |
|---|---|
claude plugin validate <dir> |
세션 없이 오타 난 이벤트, 잘못된 manifest, 읽을 수 없는 module을 잡음 |
claude plugin test (mod 없는 디렉터리) |
내 환경에서 mod가 로드될 수 있는지 확인 |
| transcript의 흐린 줄 | hot reload 세션에서 로드 실패·hook 건너뜀·거부를 보여 줌 |
debug log (--debug, --debug-file) |
모든 로드·거부·hook 실패·거부된 결과를 기록 |
/plugin의 mods active 줄 |
세션이 로드한 mod 확인 |
상세
mod가 아무것도 하지 않는 이유 찾기 (Find out why a mod does nothing)
두 가지를 확인합니다. Claude Code가 mod 파일에서 읽는 내용, 그리고 무언가를 건너뛸 때 쓰는 줄입니다.
첫째, 셸에서 mod 디렉터리로 claude plugin validate를 실행합니다. 예: claude plugin validate ./first-mod. 세션을 시작하지 않고도 오타 난 이벤트, 잘못된 manifest, Claude Code가 읽을 수 없는 module을 잡습니다.
둘째, module이 로드되지 않거나, hook이 건너뛰어지거나, 다른 mod가 내 mod를 거부하면 Claude Code는 mod 이름이 들어간 줄 하나를 씁니다. 읽는 위치는 세션에 따라 다릅니다.
- 플러그인 디렉터리를 hot reload하는 세션: transcript의 흐린 줄.
--plugin-dir로 시작한 interactive 세션, 또는 Claude가 쓴 mod에 대해 hot reloading을 켠 세션입니다. - 그 외 interactive 세션(예: marketplace에서 설치한 mod를 실행하는 세션): debug log에만.
claude --debug로 세션을 시작하세요. --plugin-dir를 쓴claude -p실행: 기본 텍스트 출력 형식에서는 stderr. 다른 mod의 거부는 debug log에만 갑니다.
mod가 로드될 수 있는지 확인 (Check whether mods can load)
mod를 설치하지 않고 내 환경에서 mod가 로드될 수 있는지 보려면, mod가 없는 디렉터리에서 셸로 claude plugin test를 실행합니다. 세션은 필요 없습니다.
| 메시지에 포함된 내용 | 의미 |
|---|---|
no hooks module to load |
mod를 로드할 수 있음. 이 디렉터리에서 테스트할 mod를 찾지 못했을 뿐 |
hooks modules are turned off here |
설정이 mod를 막고 있음: 내 settings의 disableAllHooks, 또는 조직 정책 |
hooks modules are turned off in this process: the rollout switch served off |
Anthropic이 설치된 mod를 원격으로 껐음 |
hooks modules are turned off in this process: the rollout switch was saved off by an earlier session |
이전 세션이 저장한 값(오래됐을 수 있음)을 썼음. claude를 한 번 시작해 갱신한 뒤 다시 실행 |
조직은 자기 mod만 허용하는 allowManagedModsOnly도 설정할 수 있는데, 이 명령은 그것을 보고하지 않습니다. 그 경우 내가 설치한 mod는 Claude Code가 거부하고 아래 내장 guard 메시지가 이유를 알려 줍니다.
mod가 로드되지 않음 (The mod doesn't load)
mod가 추가하는 것이 하나도 나타나지 않습니다. 명령도, 그림도, 동작 변화도 없습니다.
버전이 너무 오래됨
사용할 버전과 확인 방법을 보세요.
mods active 줄에 mod 이름이 없음
/plugin의 mods active 줄에 mod 이름이 없으면 hooks module이 로드되지 않은 것입니다. Claude Code가 거부했다면 debug log에 hooks module, mod 이름, not loaded:로 시작하는 줄이 있습니다. 예: --plugin-dir로 로드한 mod라면 hooks module first-mod@inline not loaded: disableAllHooks in managed settings.
- 콜론 뒤 이유를 읽고 아래 거부 메시지 표에서 찾으세요.
- 그런 줄이 없으면 이 그룹의 다른 항목을 차례로 확인하세요.
- 일부 설정은 mod만 막고 플러그인의 나머지는 동작하게 둡니다. Turn mods on or off에 그 설정들이 있습니다.
claude -p 실행이 hooks module not loaded를 출력
줄은 mod 이름으로 시작하고 stderr로 갑니다. hooks module이 거부된 것입니다. non-interactive 실행에는 transcript가 없어 메시지가 stderr로 갑니다. 콜론 뒤 이유를 읽고 거부 메시지 표에서 찾으세요.
거부 메시지 (Refusal messages)
debug log에서 각 메시지는 hooks module, mod 이름, not loaded: 뒤에 나옵니다.
| 메시지 시작 | 의미 |
|---|---|
hooks modules are turned off for installed plugins in this process: the rollout switch served off |
Anthropic이 설치된 mod를 원격으로 껐음 |
hooks modules are turned off for installed plugins in this process: the rollout switch was saved off by an earlier session |
이전 세션이 저장한 값(오래됐을 수 있음)을 썼음. Claude Code를 다시 시작해 갱신 |
disableAllHooks in managed settings |
조직이 설치된 플러그인의 hook을 껐음 |
only managed plugins and built-in plugins run |
allowManagedHooksOnly가 설정됐거나, managed settings가 아닌 settings 파일에 disableAllHooks가 설정됨 |
installed plugins that are not managed load no hooks module in this mode (--bare) |
Claude Code를 --bare로 시작함 |
another plugin of that name loads first |
활성화된 다른 플러그인이 같은 이름을 쓰고 그 이름을 차지해 내 hooks module이 로드되지 않음 |
내장 guard 메시지 (Messages from the built-in guard)
managed settings가 있는 머신, 또는 credential이 Team·Enterprise /login인 세션에서는 내장 guard가 mod나 mod의 답을 거부할 수 있습니다. 각 메시지는 조직 관리자가 규칙을 바꿀 때 설정하는 옵션 이름을 담고 있습니다.
| 메시지에 포함된 내용 | 의미 | 나타나는 곳 |
|---|---|---|
mods are limited to your organization's by policy (allowManagedModsOnly) |
조직이 자기 mod만 허용해 내 mod가 거부됨 | debug log, 그리고 플러그인 디렉터리를 hot reload하는 세션의 transcript |
tried to lift a deny rule in your settings |
mod의 tool.check hook이 deny 규칙이 거부하는 호출을 승인함. 호출은 계속 거부됨 |
transcript와 debug log, 세션에서 mod마다 한 번. claude -p 실행에서는 debug log에만 |
the deny rules in your settings could not be checked for this call, so it is refused |
mod가 승인한 호출을 검사하다 guard가 실패해 호출을 거부함 | 거부된 호출에 대해 Claude가 읽는 reason |
validate는 통과하는데 hooks 줄이 없음
hooks/hooks.json에 modules 키가 없거나 철자가 틀렸습니다. "modules": ["./register.js"]를 추가하세요.
hooks module did not load
줄은 mod 이름, hooks module did not load:, 이유 순서입니다. 문제가 내 코드에 있으면 파일과 줄 번호가 나옵니다. 예를 들어 top-level 코드가 throw해서 Claude Code가 module을 로드하지 못한 경우입니다.
- 이유가 지목한 오류를 고치세요.
- 이유가
; the version loaded before is unloaded로 끝나면 지금 실행 중인 버전이 없습니다. 오류를 고친 뒤 세션에서/reload-plugins로 다시 로드하세요. - 직접 쓰지 않고 설치한 mod라면 작성자에게 수정을 요청하세요.
options do not fit plugin.json userConfig
줄은 mod 이름, hooks module did not load: options do not fit plugin.json userConfig:, 이유 순서입니다. 옵션이 userConfig 필드 검증에 실패했습니다. 예: 필드의 max보다 큰 숫자, 값이 없는 필수 필드.
값을 설정하거나 바꾸세요. 줄 끝에 settings.json의 해당 pluginConfigs 항목이 나옵니다.
code nested too deep to scan: more than 2000 scopes
줄은 mod 이름, hooks module did not load:, 파일, code nested too deep to scan: more than 2000 scopes 순서입니다. hooks module 파일은 함수·블록·루프 같은 scope를 2,000단계보다 깊게 중첩할 수 없습니다. claude plugin validate도 같은 이유를 보고합니다.
scope 중첩이 얕아지도록 코드를 다시 쓰세요.
the engine ran out of stack linking the file and its imports
hooks module의 코드가 너무 깊게 중첩됐거나 import 체인이 너무 길어 Claude Code가 로드하지 못했습니다. 줄은 mod 이름, hooks module did not load:, 파일 이름, 이 이유 순서입니다.
그 파일과 import로 닿는 파일에서 가장 깊게 중첩된 부분을 찾아 얕게 다시 쓰거나 import 체인을 줄이세요. 설치한 mod라면 작성자에게 요청하세요.
the parser stopped 또는 the engine ran out of stack loading the file
hooks module 파일 하나의 코드가 너무 깊게 중첩돼 Claude Code가 읽다가 stack이 부족해졌습니다. 줄은 mod 이름, hooks module did not load:, 파일 이름, 그리고 다음 중 하나입니다.
code nested too deep to scan (the parser stopped: <message>)the engine ran out of stack loading the file (code nested too deep): <message>
이유에는 줄 번호도, 어떤 종류의 코드가 중첩됐는지도 없으므로 파일에서 가장 깊게 중첩된 부분을 직접 찾아 얕게 다시 쓰세요. 설치한 mod라면 작성자에게 요청하세요.
처음 연 디렉터리에서 mod가 하나도 로드되지 않음
그 디렉터리의 trust prompt에 답하지 않았습니다. 그 디렉터리에서 claude로 interactive 세션을 시작하고 처음 나오는 trust prompt를 수락하세요.
설치한 플러그인이 하나도 로드되지 않음
--safe-mode로 Claude Code를 시작했습니다. 플래그 없이 시작하세요.
Claude Code가 hot reloading 활성화를 더 이상 묻지 않음
interactive 세션에서 Claude가 mod를 썼는데 아무것도 로드되지 않고, Claude Code가 hot reloading을 켤지 다시 묻지 않는 경우입니다.
- 질문이 선택된 답 없이 세 번 끝나면 hot reloading은 꺼진 채로 유지됩니다.
- 예:
askUserQuestionTimeout을 설정했고 답하기 전에 시간이 지나면 그렇게 끝납니다. Claude Code가AskUserQuestion이 쓰는 질문 대화상자로 묻기 때문에 이 설정이 적용됩니다. - 직접 닫은 질문은 세 번에 포함되지 않습니다.
mod를 실행하려면 mods 폴더에서 디렉터리를 복사해 나온 뒤, 셸에서 --plugin-dir로 새 세션을 시작하세요. 예: claude --plugin-dir ~/mods/git-branch.
hook이 건너뛰어지거나 mod가 unload됨 (A hook is skipped or a mod is unloaded)
mod는 로드됐지만, 그 뒤 Claude Code가 hook 하나를 건너뛰거나 mod를 unload했습니다.
hook skipped
줄은 mod와 이벤트, hook skipped:, 이유 순서입니다. 예: first-mod: tool.call hook skipped: threw Error: boom. hook이 throw했거나, 시간 한도를 넘었거나, 잘못된 형태의 결과를 반환했습니다. 이 줄은 mod가 reload될 때까지 이벤트와 실패 종류마다 한 번 나옵니다.
오류를 고치세요. debug log에는 발생할 때마다 줄이 있습니다.
no command.run hook answered it
mod가 추가한 명령을 실행했는데 응답이 mod와 명령을 지목하며(예: first-mod registered /tally but no command.run hook answered it) hook을 추가하라고 합니다. 명령이 답 없이 체인 끝에 도달하면 나오며, 두 경우가 있습니다.
- 어떤 hook도 명령에 답하지 않음: module에
command.runhook이 없거나, hook의 필터가 다른 명령을 지정하거나, hook이next(e)를 반환함 - Claude Code가 hook을 건너뜀: 이유는 위
hook skipped에 있습니다.$.ui.open에focus: false를 넘기는 것도 그 경로 중 하나입니다.
module에 이미 그 hook이 있다면 command.run을 지목하는 hook skipped 줄에서 이유를 찾으세요. 그 명령을 실행하는 테스트도 같은 이유로 실패합니다.
it crashed the hooks worker
줄은 mod 이름으로 시작합니다. 예: first-mod was unloaded: it crashed the hooks worker. 설치된 mod들은 worker thread 하나를 공유합니다. worker가 응답을 멈추거나 crash했고, Claude Code가 원인을 이 mod로 추적해 unload했습니다. await 없이 도는 루프처럼 thread를 막는 hook이 원인 중 하나입니다.
hook을 고치세요.
its session.start ran again in a fresh copy
줄은 mod 이름으로 시작하고 $.prompt.submit, $.command.run, $.agent.spawn 호출 하나를 지목합니다. 예: 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가 mod의 module을 다시 로드했고(예: hooks worker가 crash해 교체된 뒤), 새 사본의
session.starthook이 실행됐습니다. - 지목된 호출은 다시 실행되지 않고 첫 실행의 결과로 resolve됐으므로, 프롬프트 제출·명령 실행·서브에이전트 시작이 두 번 일어나지 않습니다. hook의 나머지는 평소대로 실행됐습니다.
- 고칠 것은 없습니다.
- v2.1.292 이전에는 호출이 두 번째로 실행돼 프롬프트 제출, 명령 실행, 서브에이전트 시작이 두 번 일어났습니다.
This mod's change didn't load 또는 the earlier version is no longer running
이 세션에서 Claude가 작성한 mod의 변경을 로드하지 못했습니다. transcript 줄은 mod 이름으로 시작해 이유로 끝납니다.
This mod's change didn't load, so the earlier version is still running: <reason>.This mod didn't load, and the earlier version is no longer running: <reason>.
Claude는 이 줄을 보지 못하므로, 고쳐 달라고 할 때 다음 메시지에 이 줄을 붙여 넣으세요.
$.agent.register refused: the hooks module that made the call is no longer loaded
줄은 mod 이름으로 시작합니다. 예: first-mod: $.agent.register refused: the hooks module that made the call is no longer loaded (it was reloaded or removed). 에이전트는 등록되지 않습니다. 호출 전에 mod가 reload 또는 unload됐습니다. reload는 hooks module의 새 사본을 로드하는데, 이 호출은 아직 반환하지 않은 hook처럼 옛 사본에서 아직 돌던 코드에서 나왔습니다.
- hook이 이 rejection을 catch하지 않으면 실패하고 Claude Code가 건너뜁니다.
- 계속 로드돼 있을 사본에서 에이전트를 등록하려면
session.starthook에서 호출하세요. 이 hook은 reload 뒤 새 사본마다 다시 실행됩니다.
mods that run in the hooks worker are off for this session
줄은 hooks: mods that run in the hooks worker are off for this session: it crashed 3 times입니다. worker가 세 번 멈췄고 Claude Code가 원인을 한 mod로 추적하지 못해, 조직이 설치한 mod를 포함해 내장이 아닌 모든 mod를 unload했습니다. 이 줄은 모든 interactive 세션의 transcript에 나옵니다.
/reload-plugins로 다시 로드하세요.
도구 호출이 거부됨 (A tool call is denied)
mod가 로드되고 hook이 실행되는데, mod가 건드린 도구 호출이 거부됩니다.
a hook changed this call's input after the model wrote it
auto mode에서 거부된 도구 호출이 이 reason을 냅니다. 서버 측 classifier가 검토한 뒤에 hook이 도구 호출 입력을 바꿔, 그 검토가 실제로 실행될 내용을 다루지 못합니다. 그 hook은 mod의 tool.call·turn.step hook이거나 PreToolUse settings hook일 수 있으며, 메시지는 어느 쪽인지 말하지 않습니다.
메시지는 Claude에게 기록된 그대로 호출을 한 번 더 하라고 알립니다. 그것도 거부되면 hook이 매번 입력을 바꾸는 것이므로, mod나 hook을 끄거나 auto mode를 나와 직접 호출을 승인하세요.
settings의 deny 규칙에 관한 메시지
tried to lift a deny rule in your settings와 the deny rules in your settings could not be checked for this call, so it is refused는 모두 내장 guard에서 나옵니다. 위 내장 guard 메시지 표를 보세요.
턴을 멈춘 뒤 toast가 나타남 (A toast appears after a turn is stopped)
Stopped: type a message to continue; a mod cannot resume work after Stop
Esc 등으로 턴을 멈춘 뒤 mod가 스스로 작업을 시작하려 했고 Claude Code가 막았다는 뜻입니다. 고칠 것은 없습니다.
- 다음 메시지를 보내면 mod가 다시 작업을 시작할 수 있고, 그 작업 일부는 저절로 돌아옵니다.
- mod에서 기대한 것이 돌아오지 않으면 다시 요청하거나 mod 명령을 다시 실행하세요.
- mod 작성자라면 Calls and background work after the user interrupts a turn을 보세요.
그림이 나타나지 않거나 반응하지 않음 (A drawing doesn't appear or respond)
mod는 로드됐지만 pane, band, toast, 컨트롤이 기대대로 동작하지 않습니다.
다른 mod의 band만 보이고 내 band는 안 보임
프롬프트 위 band는 하나이고 모든 mod가 공유합니다. 내 mod보다 먼저 실행되는 mod가 next(e)의 결과를 넣지 않은 트리를 반환하면 내 band를 대체합니다. 둘 다 보이게 하려면 그 mod의 hook을 바꾸거나 작성자에게 요청하세요.
- 뒤의 band 유지: 트리에서
Box의 children 안에await next(e)의 결과를 넣습니다. Pick where to draw의 Band above the prompt 탭과 같은 방식입니다. - 트리 유효성 유지: 그
Box와 그것을 감싼 어떤Box에도width,height,minWidth,minHeight,position,top,left,right,bottom,display,overflowprop을 주지 마세요.
그 mod를 찾으려면 debug log를 쓰고 answered ui.render without next()를 검색합니다.
other-mod (user) answered ui.render without next()같은 줄이next(e)를 호출하지 않고 트리를 반환한 mod를 지목합니다.- 이 줄은 render site를 지목하지 않으므로 pane만 그리는 mod도 나올 수 있습니다.
next(e)를 호출하고 결과를 버린 mod는 줄이 없으므로 내 mod보다 앞의 hook도 확인하세요.
mod 자신의 hook이 반환한 트리가 유효하지 않을 때도 그 mod의 band만 빠지고 다른 mod의 band는 남습니다. 어느 mod가 왜 그런지는 debug log를 쓰고 ui.render hook skipped를 검색해 찾습니다(아래 항목 참고).
pane이나 band가 비어 있거나 Claude Code의 기본 내용이 보임
hook이 반환한 트리가 유효하지 않았습니다. transcript나 debug log의 hook skipped 줄(위 "hook이 건너뛰어지거나 mod가 unload됨" 참고)이 mod와 이유를 알려 줍니다. pane 안의 Box라면 다음과 같습니다.
first-mod: ui.render hook skipped: returned the wrong shape (a tree Pane refuses: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse)
이유가 가리키는 것을 고치세요. 이유가 잘려 있으면 debug log를 쓰고 a hook returned a tree that does not validate를 검색해 나머지를 읽습니다.
줄이 site 이름 바로 뒤에 refused:라고 한다면(예: ui.render (Pane) refused:) 아래 "ui.render 줄에 refused" 항목을 보세요.
ui.render 줄에 refused
ui.render (<site>) refused:, 또는 debug log의 ui.render (<site>): the chain settled on a tree that does not validate는 그 site의 트리가 크기 한도를 넘었다는 뜻입니다. 두 줄 모두 render site와 이유를 차례로 보여 주며, 이유가 한도를 가리킵니다.
그 site에 그리는 mod들의 ui.render hook이 더 작은 트리를 반환하도록 바꾸거나 작성자에게 요청하세요. transcript 줄이 hooks로 시작하면 로드된 mod 둘 이상이 그 site에 ui.render hook을 갖고 있으니 각 mod의 트리를 확인합니다. 여러 mod의 프롬프트 위 band가 32단계보다 깊게 중첩되면 줄은 다음과 같습니다.
hooks: ui.render (AbovePrompt) refused: deeper than 32; nothing was drawn
v2.1.307 이전에는 어느 site든 유효하지 않은 트리를 모두 refused: 줄로 보고했고, Pane과 AbovePrompt에서는 줄이 ; the engine drew its own으로 끝났습니다. 그 버전에서는 이유가 가리키는 것을 고치세요.
needs a key, is drawn twice, key each once
ui.render hook이 반환한 트리의 요소에 유효한 key가 없거나, 두 요소가 같은 key를 씁니다. 받은 메시지를 찾으세요.
<Input> needs a key또는<Select> needs a key: 요소에keyprop이 없거나,key가 비었거나key: 3처럼 문자열이 아닙니다. 비어 있지 않은 문자열을key로 주세요.<Button> needs a key: 버튼에 비어 있지 않은 문자열key를 주세요.is drawn twice; each takes its own key: 메시지가 가리키는 종류의 두 요소가 같은key를 씁니다. 예:Input "size" is drawn twice; each takes its own key. 요소마다 다른key를 주세요.- 테스트의
press에서key each once: 넘긴 key를 가진 버튼이 그림에 둘 이상 있습니다. 라벨이 같고keyprop이 없는 버튼들은 그 라벨을 key로 공유합니다. 버튼마다 다른key를 주세요.
ui.render 줄에 threw while drawn
줄은 render site, threw while drawn:, 오류 순서입니다. 예: first-mod: ui.render (ToolUse) threw while drawn: <error>; the engine drew its own. Claude Code가 ui.render hook이 반환한 트리를 그리다가, 또는 hook이 next에 넘긴 props로 site를 그리다가 그 오류를 만났습니다. the engine drew its own으로 끝나면 site에 Claude Code의 기본 내용이 보입니다.
오류를 읽고 원인이 된 hook의 값을 고치세요. v2.1.289 이전에는 transcript 행에서 이 오류가 나면 Claude Code exited after an unrecoverable interface error로 세션이 끝났습니다.
the module failed without a message
Client가 throw new Error()처럼 메시지 없는 오류로 실패했습니다. 그 자리의 줄은 my-mod: Client client/spinner.js: the module failed without a message와 같습니다.
Client 코드에서 throw를 찾아 오류에 메시지를 주세요. 그러면 줄에 그 메시지가 나옵니다. v2.1.289 이전에는 이유 대신 Error가 나왔습니다.
$.ui.open이 실행되는데 pane이 나타나지 않음
호출이 사용자 동작에서 나오지 않았고, 터미널 폭이 그 pane에 필요한 폭보다 좁습니다.
명령이나 버튼에서 pane을 열거나, 호출의 isPlaced 결과를 확인하세요. Open a pane at the right time을 참고하세요.
toast가 나타나지 않음
interactive 터미널 세션에서 mod가 $.ui.toast를 호출하는데 toast가 안 보이는 경우입니다. 호출이 실행됐는지 아래 debug log에서 mod 이름과 toast 텍스트가 든 줄로 확인합니다. 예: $.ui.toast (first-mod): build finished. 그다음 다음 원인을 확인합니다.
- 호출 줄이 없음: Claude Code가 호출을 거부한 이유를 담은 줄을 찾으세요. 예:
first-mod: $.ui.toast dropped: timeoutMs is a whole number of ms, 1 to 60000. - pane이 toast를 붙잡고 있음: 내 mod나 다른 mod가 현재 보이는 pane을 열 때
holdToasts를 넘겼습니다. pane을 닫으면 hold가 끝납니다. 계속 열려 있어야 하는 내 pane이라면$.ui.open호출에서holdToasts를 빼고 pane을 다시 여세요. - toast가 프롬프트 아래에 있음: classic renderer에서는 프롬프트 아래 오른쪽을 보세요. 거기서 toast는 오른쪽 위 상자가 아니라 mod 이름으로 시작하는 한 줄입니다.
- mod가 더 새 toast를 띄움: classic renderer에서는 mod의 새 toast가 표시 중이거나 대기 중인 toast를 대체할 수 있습니다. debug log에 옛 toast의 줄이 따로 있으며, 표시 중이었으면
gave way, cut short, 한 번도 안 보였으면gave way, unseen으로 끝납니다. 두 메시지를 모두 보이려면 toast 하나에 담으세요. - 그려지기 전에 시간이 다 됨: fullscreen rendering에서는 toast를 한 번에 최대 세 개까지 그리므로, toast가 그려지기 전에 시간이 끝날 수 있습니다. debug log에
left the stack, never drawn으로 끝나는 줄이 따로 있습니다. 여러 개를 한꺼번에 띄운다면 메시지를 toast 하나에 담으세요.
v2.1.290 이전에는 mod에 대해 마지막으로 보인 toast 이후 2초 안에 띄운 toast를 Claude Code가 버렸고, debug log에 within 2000ms of the last; dropped가 나왔습니다.
band에 plugin panel hidden이 보임
band가 접혀 있습니다. Ctrl+X 다음 Ctrl+A(또는 그 대신 바인딩한 키)를 누르거나, fullscreen rendering에서 첫 행의 [-]를 클릭하면 접힙니다. 펼치거나 Claude Code를 다시 시작할 때까지 접힌 상태이며, 그동안 hotkey나 action 바인딩은 그 안의 버튼을 누르지 않습니다.
펼치려면 행에 나온 키(기본 Ctrl+X 다음 Ctrl+A)를 누르거나, fullscreen rendering에서는 행을 클릭하세요.
hotkey가 동작하지 않음
pane이나 band에 키보드 포커스가 없거나, 버튼이 접힌 band 안에 있거나, 그림이 버튼 hotkey가 없는 VS Code 확장에 있습니다.
- 키보드 포커스 없음: Ctrl+X 다음 Tab을 누르거나, fullscreen rendering에서는 pane이나 band를 클릭하세요. pane이 열릴 때 포커스를 가지게 하려면 명령에서
focus: true로 여세요. - 버튼이 접힌 band 안에 있음: band에
▸ plugin panel hidden으로 시작하는 흐린 행 하나가 보입니다. 행에 나온 키(기본 Ctrl+X 다음 Ctrl+A)로 펼치세요. - VS Code 확장: 버튼을 클릭하거나, 포커스가 있을 때 Enter를 누르세요.
터미널에서는 그려지는데 Desktop 앱이나 VS Code에서는 안 됨
그 앱이 site나 요소를 그리지 않거나, VS Code 확장이 mod에 대해 아무것도 그리지 않는 세션입니다. mod의 다른 hook은 계속 실행됩니다.
- 그 앱에서 site나 요소를 그리지 않음: 레퍼런스의 render sites 표와 elements 표를 확인하세요. 앱에 없는 요소라면 hook에서
e.surface를 확인해 그 앱이 그릴 수 있는 트리를 반환하세요. - VS Code 확장이 2.1.299보다 오래됨: 채팅 패널은 확장 버전 2.1.299부터 mod를 그립니다. VS Code의 Extensions 뷰에서 버전을 확인하고 업데이트하세요.
- 확장이 2.1.304보다 오래됐고 세션이 feature flag를 가져오지 않음: 확장을 업데이트하거나, VS Code 통합 터미널에서
claude를 실행하세요. Amazon Bedrock, Google Cloud의 Agent Platform, Microsoft Foundry 세션은 이 fetch를 건너뜁니다. Claude apps gateway 세션 등 그 밖의 경우는 Features that need feature-flag fetching을 보세요.
편집이나 값이 사라짐 (An edit or a value is lost)
mod는 실행되지만, 내가 한 변경이나 mod가 보관한 값이 없습니다.
편집이 반영되지 않음
설치한 플러그인을 편집하고 있습니다. Claude Code는 설치된 버전의 캐시 사본을 실행합니다. 작업 사본을 가리키는 --plugin-dir로 개발하세요. 예: claude --plugin-dir ./first-mod. 저장하면 reload됩니다.
module이 reload되면 값이 초기화됨
module 수준 변수는 reload마다 다시 초기화됩니다. 값을 $.state나 $.store에 보관하세요.
/clear, /resume, /branch 뒤에 값이 초기화됨
값이 초기화되거나 저장된 값이 기본값으로 바뀝니다. 이 명령들은 모두 $.state를 기본값으로 되돌리고, session.start는 다시 발생하지 않습니다. classic.SessionStart hook에서 저장된 값을 다시 로드하세요.
settings.read hook이 반환한 key가 적용되지 않음
Claude Code 자체 읽기에 권한 규칙이나 env를 반환하면, 그 규칙은 도구 호출에서 검사되지 않고 env 항목은 환경 변수가 되지 않습니다. 둘 다 설정 파일을 쓰고, env는 $.env.set으로도 됩니다.
다른 key라면 어떤 mod가 어느 버전부터 settings.read를 받는지 확인한 뒤, debug log에서 settings.read를 검색해 다음 줄을 찾으세요.
| 로그 줄 | 의미와 조치 |
|---|---|
내 mod 이름 뒤의 settings.read hook skipped |
내 hook이 실패했습니다. 줄이 알려 주는 오류를 고치세요(위 hook skipped 참고). |
내 mod 이름이 앞에 나오는 줄의 settings.read bypassed by cc-plugin-sec-default |
내장 guard가 내 hook을 건너뛰었습니다. 조직 관리자에게 조직 mod로 설치해 달라고 요청하세요. |
settings.read: the answer for <key> is no value the key can hold |
hook이 그 key에 반환한 값을 Claude Code가 거부했습니다. 내 hook일 수도, 다른 mod의 hook일 수도 있습니다. 아래 같은 이름의 항목을 따르세요. |
settings.read: the merge never settles for <key> |
줄이 가리키는 key는 설정 출처의 값을 유지합니다. 설정 파일에 설정하세요. |
mod 이름 뒤의 answered settings.read without next() |
그 mod가 내 mod보다 먼저 실행된다면 그 읽기에서 내 hook은 실행되지 않았습니다. 그 mod를 끄거나, 조직이 배포한 mod라면 관리자에게 끄도록 요청하세요. |
settings.read: refused to the engine |
Claude Code 자체 읽기가 거부되어 내 값이 적용되지 않았습니다. 아래 같은 이름의 항목에서 무엇이 거부했는지 찾으세요. |
어느 줄도 설명하지 못하면 내 mod보다 먼저 실행되는 mod 가운데 그 key를 바꾸는 settings.read hook이 있는지 확인하세요. 그 mod를 끄거나 조직 관리자에게 요청합니다. 그런 hook이 없다면 설정 파일에 key를 설정하세요.
the answer for <key> is no value the key can hold
이 debug log 줄은 settings.read hook이 해당 key 하나에 반환한 값을 Claude Code가 거부했다는 뜻입니다.
settings.read: the answer for <key> is no value the key can hold; the settings' own value stands
반환한 값이 타입이나 범위 등에서 그 key의 schema에 맞지 않았습니다.
- 내 값이 schema에 맞지 않음: settings reference의 그 key 항목이 허용하는 값을 반환하세요.
- 내 값은 맞음: 맞지 않는 값은 다른 mod의
settings.readhook에서 왔습니다. 그 mod를 찾으려면 아래 "settings.read: refused to the engine"의 mod를 하나씩 끄는 절차를 따르되, 새 로그마다refused to the engine대신 이 줄을 검색합니다.
값이 맞지 않는 동안 그 key는 어떤 hook이 답하기 전 설정 출처에서 병합된 값을 유지합니다. 줄은 이를 settings' own value라고 부릅니다.
settings.read: refused to the engine
Claude Code 자체 읽기가 거부되면 debug log에 이 줄이 나오고, Claude Code는 모든 hook의 값을 버립니다. settings.read hook이 { deny: reason }으로 그 읽기를 거부했다면 줄에 그 hook의 이유가 들어 있습니다.
settings.read: refused to the engine (engine: $.settings.read: <reason>); the settings' own values stand
괄호 안의 이유를 내 코드에서 검색하세요.
- 내 코드에 있음: 내 hook이 읽기를 거부했습니다.
next.origin이 Claude Code 자체 읽기를 가리킬 때는{ value }를 반환하게 하세요. - 내 코드에 없음: 다른 mod를 하나씩 끄세요. 조직이 배포한 mod라면 관리자에게 끄도록 요청합니다. 하나 끌 때마다:
- 셸에서
claude --debug-file ./settings-read-2.log에 세션이 원래 쓰던 플래그를 붙여 시작합니다. 매번 새 경로를 씁니다. - 그 파일에서
refused to the engine을 검색합니다. 줄이 있으면 다음 mod를 끄고, 없으면 마지막으로 끈 mod가 읽기를 거부한 것이니 그대로 꺼 둡니다.
- 셸에서
다른 mod를 모두 껐는데도 줄이 남으면, 내 hook이 반환하는 key를 설정 파일에 설정하세요. 읽기가 거부된 동안에도 그 값은 유지됩니다.
debug log 읽기 (Read the debug log)
debug log에는 Claude Code가 로드하거나 거부한 모든 module, 실패한 모든 hook, 거부한 모든 결과가 한 줄씩 기록됩니다. transcript에 아무것도 없을 때 볼 곳입니다. 셸에서 --debug로, 또는 위치를 정하려면 --debug-file <path>로 Claude Code를 시작합니다.
claude --debug-file ./mod-debug.log --plugin-dir ./first-mod
다른 터미널에서 파일을 따라가며 mod 이름으로 필터링합니다.
tail -f ./mod-debug.log | grep first-mod
로드된 mod는 이름과 처리하는 이벤트를 나열한 줄이 있습니다. --plugin-dir로 로드한 mod는 이름 뒤에 @inline이 붙습니다.
hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render
- log에 직접 줄을 쓰려면
$.ui.log에 두 번째 인자를 줍니다. 예:$.ui.log('message', { to: 'debug' }). 두 번째 인자가 없으면$.ui.log는 transcript에 흐린 줄을 추가합니다. --plugin-dir로 로드한 mod를 편집하는 동안 transcript에는 reload마다 mod 이름과 hook을 나열한 줄이 나옵니다. 저장한 내용이 module을 깨뜨리면 줄에reload failed, the previous version stays loaded:와 이유가 나오고, Claude Code가 다음에 플러그인을 reload할 때(예:/reload-plugins실행)까지 마지막으로 동작한 버전이 계속 실행됩니다.
체크리스트
-
claude plugin validate <dir>로 manifest,modules키, 이벤트 이름을 확인했다. - mod 없는 디렉터리에서
claude plugin test로 내 환경에서 mod가 로드될 수 있는지 확인했다. -
/plugin의mods active줄에 mod 이름이 있는지 봤다. - 설치한 mod라면
claude --debug또는--debug-file로 debug log를 남기고 mod 이름으로 검색했다. -
not loaded:뒤 이유를 거부 메시지·내장 guard 메시지 표와 대조했다. - 그림 문제라면
ui.render hook skipped,refused:(크기 한도),does not validate,answered ui.render without next()줄을 찾았다. -
settings.read값이 적용되지 않으면 debug log에서settings.read를 검색해 줄별 조치를 따랐다. - 설치된 사본이 아니라
--plugin-dir작업 사본으로 개발하고 있다. - reload·
/clear뒤 유지돼야 할 값은$.state/$.store와classic.SessionStarthook으로 복원한다.
다음 단계
- mod 테스트: 문제가 세션에 닿기 전에 잡습니다.
- 플러그인 문제 해결: mod에 국한되지 않은 플러그인 설치·로드 문제를 다룹니다.
- Mods 레퍼런스: 한도, 설정, render site, 요소 표를 확인합니다.
기준일
이 문서는 2026-11-03에 공식 Troubleshoot a mod 페이지를 기준으로 작성했습니다. 메시지 문구는 버전에 따라 바뀔 수 있으니 공식 원문을 함께 확인하세요.