Claude Code 설정이 적용되지 않을 때: /status·claude doctor로 확인하는 순서

게시 읽는 시간 약 12분 문제 해결

훅의 matcher를 문자열 대신 ["Edit", "Write"] 같은 배열로 적어 둔 프로젝트에서 터미널로 claude doctor를 돌려 봤습니다. 어느 파일의 어느 키가 틀렸는지는 물론이고, 고칠 모양("Edit|Write")까지 짚어 주더라고요.

이런 스키마 오류가 있으면 그 설정 파일은 통째로 거부됩니다. 훅 하나를 잘못 쓴 탓에 같은 파일의 권한 규칙까지 빠질 수 있다는 얘기예요.

반대 경우도 있었습니다. settings.json에 mcpServers를 넣고 훅 매처를 소문자 bash로 적은 파일은 claude doctor가 한 줄도 문제 삼지 않았거든요.

둘 다 아무 일도 하지 않는 설정인데요. doctor가 조용하다는 건 “타입이 맞다”는 뜻이지 “설정이 먹는다”는 뜻이 아니었습니다.

그래서 설정을 고쳤는데 그대로라면, 저는 값을 다시 고치기 전에 그 파일이 읽히기는 했는지부터 보라고 권합니다. /context·/status·/hooks로 읽혔는지 보고, claude doctor로 거부됐는지 보고, 같은 키를 위 단계 파일이 덮는지 본 다음, 그래도 모르겠으면 claude --safe-mode로 커스터마이즈를 모두 끈 세션과 비교합니다.

기준은 2026년 9월 22일 공식 문서이고, claude doctor 출력은 Ubuntu 24.04 · Claude Code 2.1.278 테스트 환경에서 직접 실행해 얻었습니다.

10월 12일에는 Windows 11 · PowerShell 5.1 · Claude Code 2.1.296에서 같은 파일로 다시 돌려 봤고, Windows에서 걸리기 쉬운 역슬래시 경로와 파일 인코딩도 확인했습니다.

규칙 자체를 쓰는 법은 allow·deny 규칙 문법과 자주 새는 패턴과 훅으로 편집 후 포맷·커밋 전 테스트 걸기에 따로 정리해 뒀습니다.

확인한 버전·환경

  • Claude Code 2.1.296 · Windows 11 · Windows PowerShell 5.1 · 확인일 2026-10-12
  • Claude Code 2.1.278 · Ubuntu 24.04 · 확인일 2026-09-22

값보다 먼저, 읽혔는지부터

훅을 settings.json에 추가했는데 /hooks를 열면 아무것도 없는 상황을 떠올려 보세요. 매처 철자부터 다시 고치기 쉽지만, 대개는 값이 아니라 파일 쪽 문제입니다. 지시가 무시되거나 설정한 기능이 안 보일 때 원인은 거의 셋 중 하나로 갈립니다.

원인 드러나는 모습
파일이 로드되지 않음 목록에 아예 없음
다른 위치에서 로드됨 목록에 있지만 경로가 다름
다른 파일이 덮어씀 목록에 있는데 동작이 다름

파일이 안 읽히고 있으면 값을 몇 번을 바꿔도 그대로입니다.

시간이 가장 오래 걸리는 건 마지막 경우예요. 파일이 목록에 보이니 읽혔다고 믿고 값만 계속 만지게 되거든요. 그래서 아래 순서를 위에서부터 밟습니다.

설정이 적용되지 않을 때 읽혔는지 확인, 파일이 거부됐는지 확인, 위 단계가 덮었는지 확인, 안전 모드로 비교의 네 단계를 차례로 거치며 각 단계에서 결과가 어떻게 갈리는지 보여 주는 그림
왼쪽 네 단계를 위에서부터 밟고, 오른쪽은 각 단계에서 결과가 갈렸을 때 볼 곳입니다.

/context로 들어왔는지 보기

세션 안에서 /context를 먼저 실행해 보세요. 지금 컨텍스트 창을 차지한 것(시스템 프롬프트, 시스템 도구, MCP 도구, 어디서 로드됐는지 표시되는 커스텀 서브에이전트, 메모리 파일, 스킬, 대화)을 범주별로 보여 주니까, CLAUDE.md·규칙·스킬 설명이 들어와 있는지 바로 보입니다. 범주 하나를 더 자세히 보려면 전용 명령을 씁니다.

명령 보여 주는 것
/memory 메모리 파일 위치
/skills 프로젝트·사용자·플러그인 스킬
/hooks 지금 적용 중인 훅
/mcp MCP 서버와 상태
/permissions 효력 있는 allow·deny 규칙
/status 읽은 설정 파일, managed 적용 여부

/context의 스킬에는 /skills가 보여 주지 않는 번들 스킬도 들어 있습니다. 하나 더 보여도 이상한 게 아니에요.

자주 걸리는 건 하위 폴더의 CLAUDE.md입니다. 하위 폴더의 CLAUDE.md는 Claude가 Read 도구로 그 폴더의 파일을 읽을 때 들어옵니다. 세션을 시작할 때도, 파일을 쓰거나 만들 때도 아니에요.

작업 폴더와 그 위쪽의 CLAUDE.md는 시작할 때 들어오고, 여러 파일은 서로 덮지 않고 이어 붙습니다. 언제 무엇이 읽히는지는 .claude 디렉터리에 무엇이 언제 읽히나에 정리했습니다.

반대로 /context에 파일이 분명히 있는데 특정 지시만 안 지킨다면, 읽기 문제가 아니라 지시를 쓴 방식의 문제일 가능성이 큽니다. 여러 뜻으로 읽히거나, 두 파일이 서로 다른 지시를 하거나, 파일이 길어 규칙 하나하나에 주의가 덜 가는 경우죠. 이쪽은 CLAUDE.md 작성법에서 다뤘습니다.

claude doctor가 잡는 것과 못 잡는 것

터미널에서 claude doctor를 실행하면 세션을 열지 않고 설치·설정 진단을 읽기 전용으로 출력합니다. 세션 안의 /doctor는 같은 점검에 더해 수정을 제안하고, 적용하기 전에 물어봅니다(쓰이지 않는 확장, 같은 폴더의 중복 서브에이전트 이름도 봅니다).

도입에서 말한 배열 매처 프로젝트를 Windows의 2.1.296에서 돌린 출력은 이렇습니다.

Invalid settings
- <프로젝트 경로>\.claude\settings.json › hooks.PreToolUse.0: Invalid hook matcher (matcher: Invalid input: expected string, received array) — a PreToolUse/PermissionRequest hook that cannot be loaded may be what guards the permissions declared beside it, so nothing it sits in is applied until the entry is fixed or removed.
- <프로젝트 경로>\.claude\settings.json › hooks.PreToolUse.0.matcher: Expected string, but received array
  Suggested fix: Hooks use a matcher + hooks array. The matcher is a string: … pipe-separated list ("Edit|Write") …

2.1.278에서는 received undefined라고만 나왔는데, 지금은 배열을 받았다고 정확히 짚습니다. 그리고 이 훅이 옆의 권한 규칙을 지키는 훅일 수 있어서, 고치기 전까지 그 안의 설정을 하나도 적용하지 않는다고 이유까지 적어 줘요.

그래서 이런 스키마 오류가 있으면 그 파일의 훅은 /hooks에 하나도 안 나옵니다. JSON 자체가 깨진 경우(예: permissions.allow 뒤의 마지막 쉼표)는 키를 짚지 못하고 파일만 가리킵니다.

Invalid settings
- <프로젝트 경로>\.claude\settings.json: Invalid or malformed JSON

2.1.278에서는 같은 파일에 Expected object, but received undefined가 나왔습니다. 버전에 따라 문구가 다르니 문구보다 파일 경로를 보세요.

Windows 경로를 JSON에 그대로 넣었을 때

Windows 경로를 settings.json에 그대로 붙여 넣으면 역슬래시가 JSON 이스케이프로 읽힙니다. 결과는 두 갈래였어요.

넣은 값 claude doctor 실제로 읽힌 값
"C:\work\other" Invalid or malformed JSON 파일 전체 거부
"C:\tools\new" 아무 말 없음 C:, 탭, ools, 줄바꿈, ew

두 번째가 위험합니다. \t와 \n은 JSON에서 탭과 줄바꿈이라 문법상 맞는 값이고, doctor는 한 줄도 문제 삼지 않았습니다. 경로가 엉뚱한 글자로 바뀌어 있는데도요.

Windows 경로는 "C:\\tools\\new"처럼 역슬래시를 두 번 적으세요.

파일 인코딩은 걱정하지 않아도 됐습니다. PowerShell로 저장하면 BOM이 붙거나 UTF-16이 되기 쉬운데, "model": "haiku" 한 줄을 UTF-8(BOM 없음·있음)과 UTF-16LE로 저장해 보니 세 경우 모두 Haiku로 돌았어요.

대화형 세션은 시작할 때 알려 줍니다. JSON이 깨졌거나 스키마가 값을 거부하면 Settings Error, 항목 몇 개만 실패하면 Settings Warning이 뜨고, 경고는 실패한 값만 건너뜁니다. -p로 도는 비대화형 실행에는 이 대화 상자가 없으니, 설정이 무시된 것 같으면 실행 뒤에 claude doctor를 돌려 보세요.

조용히 통과하는 엉뚱한 값

문제는 타입만 맞으면 뜻이 틀려도 통과한다는 겁니다. 2.1.278에서 아래 파일로 돌려 보니 Invalid settings가 한 줄도 나오지 않았고, Windows의 2.1.296에서도 같았습니다.

{
  "mcpServers": { "demo": { "command": "npx", "args": ["-y", "demo-server"] } },
  "hooks": {
    "PreToolUse": [
      { "matcher": "bash", "hooks": [{ "type": "command", "command": "echo hi" }] }
    ]
  }
}

그런데 둘 다 아무 일도 안 하는 설정이에요. settings.json은 mcpServers 키를 읽지 않고, 매처는 대소문자를 구분하는데 도구 이름은 Bash처럼 대문자로 시작합니다.

설정이 뜻밖에 동작할 때 원인은 대부분 이런 위치·문법 규칙 몇 가지로 돌아가더라고요. 증상별로 보면 이렇습니다.

  • 전역 권한·훅·env가 무시된다면 ~/.claude.json(앱 상태 파일)에 넣은 경우입니다. ~/.claude/settings.json으로 옮기세요.
  • settings.json 값이 무시된다면 같은 키가 settings.local.json에도 있는지 보세요. 로컬이 이깁니다.
  • 훅이 아예 안 걸린다면 훅을 별도 파일에 정의하지 않았는지 보세요. 프로젝트·사용자 설정에는 독립 훅 파일이 없으니 settings.json의 hooks 아래에 둡니다. hooks/hooks.json은 플러그인만 읽습니다.
  • 스킬이 안 보인다면 .claude/skills/이름.md가 아니라 .claude/skills/이름/SKILL.md로 둡니다.
  • .mcp.json의 서버가 안 붙는다면 파일을 저장소 루트에 두고(.claude/ 아래 아님) 서버는 mcpServers 키 아래에 둡니다(servers 아님).
  • 서브에이전트가 CLAUDE.md를 안 따른다면, 내장 Explore·Plan 에이전트는 원래 CLAUDE.md를 건너뜁니다. 위임 프롬프트에 지시를 다시 적어 주세요.

매처 쉼표는 버전을 탑니다. 지금은 "Edit,Write"도 두 도구를 잡지만, v2.1.191 이전에는 쉼표 매처가 전혀 맞지 않았으니 그 아래 버전이면 |를 쓰세요.

같은 키를 누가 덮었나

파일이 읽혔고 문법도 맞는데 값이 다르다면 우선순위 문제입니다. 같은 키는 managed 설정 → 명령줄 인자 → .claude/settings.local.json → .claude/settings.json → ~/.claude/settings.json 순으로 위가 이깁니다.

파일별로 무엇을 둘지는 설정 파일 우선순위: settings.json 네 곳 중 어디에 둘까에 정리했고, 여기서는 이 단계에서 놓치기 쉬운 것만 적겠습니다.

  • 목록 키는 덮이지 않고 합쳐집니다. permissions.allow를 여러 파일에 두면 모두 합쳐져요. “지운 적 없는 규칙이 왜 남아 있지?“의 답이 대개 여기 있습니다.
  • 환경 변수는 이 순서의 한 칸이 아닙니다. 변수와 키의 짝마다 정해져 있어서, 셸의 ANTHROPIC_MODEL은 어느 파일의 model보다 앞서고 ANTHROPIC_DEFAULT_MODEL은 어떤 파일도 model을 정하지 않았을 때만 쓰입니다.
  • /status는 키마다 출처를 알려 주지 않습니다. 읽은 파일과 managed 적용 여부만 보이니, 키 단위는 파일을 열어 눈으로 좁혀야 해요.
  • 그 파일이 정할 수 없는 값도 있습니다. permissions.defaultMode의 auto·bypassPermissions는 프로젝트·로컬 설정에서 적용되지 않습니다(v2.1.257 이전에는 bypassPermissions가 어디서든 됐음). 사용자·managed 설정이나 --permission-mode를 쓰세요.

팀원에게만 allow 규칙이 안 먹는다면 신뢰 단계를 의심해 보세요. permissions.allow, permissions.additionalDirectories, extraKnownMarketplaces, 대부분의 env 값은 각자 그 폴더를 신뢰한 뒤에 적용되고, deny·ask는 바로 적용됩니다.

그래도 모르겠으면 반으로 자르기

여기까지 와도 못 찾았다면 값을 더 들여다보지 말고 범위를 반으로 자르는 편이 빠릅니다.

claude --safe-mode

안전 모드는 CLAUDE.md·스킬·플러그인·훅·MCP 서버·커스텀 명령과 에이전트를 모두 끈 세션입니다. 인증·모델 선택·내장 도구·권한은 그대로 동작해요.

여기서 문제가 사라지면 커스터마이즈 중 하나가 원인이니 앞의 단계로 돌아가 좁힙니다.

조직의 managed 훅과 설정 정책은 안전 모드에서도 남으므로(관리자가 배포한 플러그인·스킬·CLAUDE.md·MCP 서버는 꺼짐), 그래도 증상이 남으면 managed 정책이나 환경 변수를 보세요.

더 확실히 떼어 보려면 CLAUDE_CONFIG_DIR를 빈 폴더로 지정해 ~/.claude 전부를 건너뛰고, .claude·.mcp.json·CLAUDE.md가 없는 폴더에서 실행합니다.

# Windows PowerShell (macOS·Linux: CLAUDE_CONFIG_DIR=~/claude-clean claude)
$env:CLAUDE_CONFIG_DIR = "$env:USERPROFILE\claude-clean"
claude
Remove-Item Env:CLAUDE_CONFIG_DIR   # 확인이 끝나면 되돌리기

테마 선택부터 시작하는 첫 실행 화면이 나오면 빈 설정 폴더가 적용된 것입니다. 여기서 문제가 사라지면 원인은 실제 설정 안에 있으니 하나씩 되돌려 넣으며 찾고, 그대로면 설정 바깥에 있습니다.

MCP 서버만 안 붙는다면 갈래가 따로 있습니다. .mcp.json의 프로젝트 서버는 한 번 승인을 받아야 하고, 그 프롬프트를 닫았으면 /mcp에서 승인할 때까지 꺼져 있어요.

command·args의 상대 경로도 흔한 원인인데, .mcp.json 위치가 아니라 Claude Code를 실행한 폴더 기준으로 풀리기 때문입니다. 실패 문구별 순서는 MCP 서버 연결 실패를 상태 줄부터 읽는 법에 있습니다.

자주 만나는 증상

/hooks에 방금 추가한 훅이 안 보입니다

훅이 설정 파일의 hooks 키 아래에 없거나, 같은 파일의 다른 항목이 스키마를 어겨 파일이 통째로 거부된 경우입니다. claude doctor부터 돌리고, 아무것도 안 나오면 훅을 별도 파일에 두지 않았는지 보세요. 저장 직후라면 몇 초 뒤 /hooks를 다시 열어 봅니다.

훅이 목록에는 있는데 발동하지 않습니다

대개 매처입니다. 도구 이름 오타, 소문자 표기, v2.1.191 이전의 쉼표 구분자가 흔해요. 이름을 Bash·Edit·Write·Read처럼 대문자로 맞추고 여러 도구는 "Edit|Write"로 씁니다.

그래도 안 되면 claude --debug로 시작해 도구를 한 번 쓰게 하고, 어떤 매처가 검사됐는지와 훅 종료 코드를 로그에서 보세요. 매처가 맞는데도 조용하면 훅이 등록·매칭·실행·해석 중 어디서 멈췄는지 가르는 순서로 이어집니다.

settings.json을 고쳤는데 세션에 반영되지 않습니다

보통은 잠깐 뒤 실행 중인 세션에 반영되고 재시작이 필요 없습니다. 세션 시작 뒤에 파일이나 .claude/ 폴더를 새로 만든 경우도 마찬가지예요.

다만 v2.1.257 이전에는 세션 시작 후 만든 .claude/ 폴더의 편집을 감지하지 못했으니, claude --version이 그보다 낮으면 다시 시작하세요. 최신인데도 그대로면 앞의 우선순위 단계를 봅니다.

권한 프롬프트에서 “다시 묻지 않음”을 골랐는데 또 묻습니다

그 선택은 로컬 파일에 allow 규칙을 저장하는데, 로컬의 allow는 프로젝트나 managed 파일의 ask 규칙을 이기지 못합니다. 항상 허용해야 한다면 ask 규칙이 있는 파일에서 고치고, 어느 범위인지는 /permissions와 /status로 좁혀 보세요.

다른 사람들이 겪은 문제

세 건 모두 2.1.278보다 앞선 버전의 보고예요.

  • bgbg(2025-11-13, #11544)는 2.0.37에서 사용자 설정의 훅이 로드되지 않아 /hooks가 No hooks configured yet을 보였고, 디버그 로그에 Found 0 hook matchers in settings가 찍혔다고 했습니다. 원인과 우회법은 나와 있지 않습니다.
  • marcstraube(2026-01-19, #19312)는 2.0.67 · Arch Linux에서 프로젝트 설정의 권한·훅이 적용되지 않고 사용자 설정 규칙만 먹었으며, 같은 로그 줄이 찍혔다고 했습니다. 원인은 없고, 우회로 권한을 모두 사용자 설정으로 옮겼다고 해요.
  • kitaekatt(2026-02-11, #25086)는 버전을 1.0.33+로 적은 보고에서, settings.local.json의 enabledPlugins가 settings.json에도 같은 키가 있을 때만 먹었다고 했습니다. 보고자는 병합이 이미 있는 키에만 덮어쓰기를 적용한다고 원인을 짚고, settings.json에 빈 enabledPlugins를 두는 우회법을 남겼습니다.

세 건 모두 파일은 디스크에 그대로 있었고, 문제를 먼저 드러낸 건 /hooks, 디버그 로그, 서로 어긋난 /plugin 탭 같은 도구의 표시였습니다. 제가 보기엔 값을 고치기 전에 로드 표시부터 읽었다면 훨씬 빨리 끝났을 상황들이에요.

마치며

설정이 안 먹을 때 가장 시간을 잡아먹는 건 값을 계속 바꿔 보는 일입니다. 직접 돌려 보니 claude doctor는 깨진 파일은 정확히 짚어 줬지만, 타입만 맞는 엉뚱한 값 앞에서는 조용했어요. 진단 도구가 조용하다고 설정이 먹는 건 아닙니다.

그러니 고친 설정이 안 먹고 있다면 터미널에서 claude doctor를 한 번 돌려 Invalid settings가 있는지부터 보고, 없으면 /context와 /hooks에서 그 파일이 정말 들어왔는지 확인해 보세요. 오류 문구가 뜨는 경우까지 포함해 어디부터 볼지는 증상으로 어느 층에서 막혔는지 가르는 순서로 이어집니다.

참고한 공식 자료

모두 2026년 9월 22일에 확인했습니다.

인용한 공개 사례

변경 이력

  • 2026-10-12 — Windows 11 · Claude Code 2.1.296에서 다시 확인했습니다. claude doctor의 배열 매처·끝 쉼표 오류 문구가 바뀐 것을 반영하고, Windows 경로의 역슬래시가 오류 없이 탭·줄바꿈으로 읽히는 경우와 BOM·UTF-16 설정 파일도 읽힌다는 결과를 더했습니다.