Found while setting up a machine. Doctor reported a green check for a configuration the agent was not actually loading.
What happened
~/.claude.json had two codemap MCP entries:
Doctor said:
OK Claude MCP: /Users/jordan/.claude.json (user scope)
But Claude Code resolves MCP servers project → local → user, so the stale local entry wins. The agent was running a binary from four months earlier while doctor reported everything healthy.
Root cause
checkScopedFile (added in #100) walks the scopes in order and reports the first that validates. Claude Code loads the first that exists, valid or not. Those are different rules, and they diverge exactly when a higher-precedence scope is present but broken — which is the case worth catching.
The failure mode is the one codemap exists to prevent: the tool says fine, reality differs.
Suggested fix
Validation order should follow load order, not skip past broken scopes:
- Find the highest-precedence scope that defines a codemap server (regardless of validity).
- Validate that one. If it fails, report MISS naming that scope — even if a lower-precedence scope would have passed.
- Only fall through to a lower scope when the higher one genuinely doesn't define an entry.
Worth also reporting when a lower scope is being shadowed, e.g.:
MISS Claude MCP: ~/.claude.json local scope (unrecognized arguments) — shadows a valid user-scope entry
That turns a silent wrong-binary situation into an actionable message.
Scope
Affects the MCP scope checks. The hooks checks are less exposed because agents merge hook settings across scopes rather than picking one, but the ordering logic is shared and worth reviewing together.
Reproduce
codemap setup --global --agent claude (writes a valid user-scope entry)
- Hand-add a
projects["<repo>"].mcpServers.codemap entry in ~/.claude.json with "args": []
codemap doctor → reports OK from user scope; Claude Code loads the broken local one
Found while setting up a machine. Doctor reported a green check for a configuration the agent was not actually loading.
What happened
~/.claude.jsonhad two codemap MCP entries:Doctor said:
But Claude Code resolves MCP servers project → local → user, so the stale local entry wins. The agent was running a binary from four months earlier while doctor reported everything healthy.
Root cause
checkScopedFile(added in #100) walks the scopes in order and reports the first that validates. Claude Code loads the first that exists, valid or not. Those are different rules, and they diverge exactly when a higher-precedence scope is present but broken — which is the case worth catching.The failure mode is the one codemap exists to prevent: the tool says fine, reality differs.
Suggested fix
Validation order should follow load order, not skip past broken scopes:
Worth also reporting when a lower scope is being shadowed, e.g.:
MISS Claude MCP: ~/.claude.json local scope (unrecognized arguments) — shadows a valid user-scope entryThat turns a silent wrong-binary situation into an actionable message.
Scope
Affects the MCP scope checks. The hooks checks are less exposed because agents merge hook settings across scopes rather than picking one, but the ordering logic is shared and worth reviewing together.
Reproduce
codemap setup --global --agent claude(writes a valid user-scope entry)projects["<repo>"].mcpServers.codemapentry in~/.claude.jsonwith"args": []codemap doctor→ reports OK from user scope; Claude Code loads the broken local one