Skip to content

doctor: reports OK from a lower-precedence scope while a broken higher-precedence one shadows it #109

Description

@JordanCoin

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:

// user scope (top-level mcpServers) — correct, written by `codemap setup`
{ "command": "/opt/homebrew/bin/codemap",
  "args": ["mcp", "--configured-version", "4.3.0", "--integration", "claude-setup"] }

// local scope (projects["<root>"].mcpServers) — hand-wired, pointing at a 4-month-old binary
{ "command": "/Users/jordan/Code/codemap/codemap-mcp", "args": [] }

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:

  1. Find the highest-precedence scope that defines a codemap server (regardless of validity).
  2. Validate that one. If it fails, report MISS naming that scope — even if a lower-precedence scope would have passed.
  3. 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

  1. codemap setup --global --agent claude (writes a valid user-scope entry)
  2. Hand-add a projects["<repo>"].mcpServers.codemap entry in ~/.claude.json with "args": []
  3. codemap doctor → reports OK from user scope; Claude Code loads the broken local one

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions