Skip to lesson

AnthropicClaude Certified Architect – Professional2026-107.3 Support debugging and operational issue resolution

Locate configuration faults before relaxing controls

Completed by the knowledge check

Learning objective

Diagnose configuration issues: instructions not loading, permission denials, MCP connection failures, and misfiring hooks.

Core idea

A team configuration is healthy when its intended behavior can be reproduced from the deployed files and launch context. A file on disk, a tool name in context, and an approved operation establish different things. Diagnose which stage failed before changing prompts or broadening access.

Assume you already know how to inspect memory locations with /memory. The operational addition is a repeatable comparison of affected and healthy sessions: loaded context, effective settings, server status, and hook evaluation. See 7.1.1 for the configuration release itself.

How it works

Start with the session that failed

Run /context to inspect the categories occupying the session: memory files, system tools, MCP tools, custom subagents, skills, and messages. The skill listing helps establish that a description was available; it does not prove that the full procedure ran. An MCP tool category likewise does not establish that its backend accepted a request.

Account for on-demand subdirectory instructions when interpreting missing launch entries.

Run /status for active settings sources and claude doctor in the terminal for read-only settings diagnostics. This matters when the same checked-in file works for one engineer but a personal or local setting changes another session. A repair belongs in the source responsible for the behavior; overwriting a project file cannot remove a managed restriction. See 7.1.2 for ownership by scope.

Before checking individual components, reproduce the symptom with claude --safe-mode. It disables CLAUDE.md, skills, plugins, hooks, MCP servers, custom commands and agents, custom output styles, and custom keybindings; authentication, model selection, built-in tools, and permissions still work. If the fault disappears, investigate the disabled customizations rather than changing unrelated access rules.

Safe mode still applies managed hooks and organizational settings policy, while managed plugins, skills, CLAUDE.md, and MCP servers are disabled. A persistent fault therefore warrants checking effective permissions, managed policy, and the environment; it does not prove that the project files are responsible.

Explain a denial before adding an allow

Open /permissions, which lists rules and the settings files they come from. Rules resolve in the order deny, ask, then allow; a narrower allow does not override a matching broad deny. If an operator reports that an approved read still fails, identify the matching rule and canonical tool name before adding duplicate approvals.

Separate a Claude Code refusal to invoke a tool from a backend authorization failure after invocation. The former needs permission diagnostics; the latter needs the service account, resource, and server response checked. Granting mcp__observability__* cannot repair an expired backend credential. Conversely, backend access does not override a Claude Code deny rule.

Preserve an intentional restriction. Record the requested operation and why it is outside the team’s policy, then use the approved escalation route. A configuration incident is not authorization to disable controls. This makes the platform team responsible for actual configuration defects while keeping access-policy decisions with their owners.

Inspect the server before changing its tool description

Use /mcp to inspect connection status and project approval. A project-scoped server in root .mcp.json needs one-time approval; a dismissed approval leaves it disabled. A failing local server may use a relative path in command or args that resolves against the launch directory. Use an absolute script path when that dependence is unintended.

For a remote entry with a url, supply its transport type; an omitted type is interpreted as stdio, so Claude Code skips a URL-only entry with a diagnostic. Put project servers under mcpServers in .mcp.json, not under mcpServers in settings.json.

A connected server with zero tools is a different fault. Select Reconnect in /mcp; if the count remains zero, launch claude --debug=mcp and inspect server stderr in the debug log. Record the failing stage and sanitized error for the integration owner. Do not rewrite the prompt to demand a tool whose definition the server never supplied.

Each /mcp observation leads to its own check: project approval, the script path, or server stderr in the debug log.

Each /mcp observation leads to its own check, project approval, the script path, or server stderr in the debug logStarts at the connection status in /mcp. A disabled server needs one-time approval. A failing local server may use a relative path in command or args, so use an absolute script path. A connected server with zero tools gets Reconnect; if the count remains zero, inspect server stderr in the debug log and record the failing stage.disabledfailingconnected, zero toolscount remains zeroConnection statusNeeds one-timeapprovalRelative path incommand or argsUse an absolutescript pathSelect ReconnectInspect serverstderr in the debuglogRecord the failingstage

Follow a hook through both filters

Run /hooks to see registered hooks grouped by event. If the hook is absent, inspect the loaded settings file and hooks key. A matcher must be a string, not an array. claude doctor reports invalid configuration; fixing the handler script alone cannot register a rejected entry.

If the hook is present, compare the event, canonical tool name, matcher, and handler’s optional if condition. Matching is case-sensitive: bash does not match Bash. A missing matcher or "*" runs for every occurrence of that event, explaining a hook that runs too often. "Edit|Write" selects either named tool.

The if field is a second filter, not a decision made inside the script. With matcher: "Bash" and if: "Bash(rm *)", a call to npm test never spawns the handler. An if on SessionStart never runs because this field is evaluated only on tool events. See 7.1.1 for its configuration definition; here, distinguish a filter miss from a handler failure.

To trace a registered hook:

  1. Set CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose for detailed matcher evaluation.
  2. Start claude --debug-file <path> to capture a known diagnostic file.
  3. Trigger the tool call whose hook behavior is in question.
  4. Inspect the log for the event, matcher evaluation, exit status, and output.

--debug writes a log rather than printing the trace to the terminal. For PreToolUse, plain stderr and exit 1 report a non-blocking failure; exit 2 blocks. A policy check that crashed is therefore not equivalent to a successful denial. Safety-hook failure behavior is covered in 7.3.4.

Key distinctions and trade-offs

ObservationNext diagnostic questionWrong repair
Instruction absent at launchIs it scoped to lazy loading?Rewrite every rule
Tool invocation deniedWhich effective rule matched?Add a broad allow
Server disabled or failedApproval, transport, path, or credentials?Change tool-selection prose
Hook registered but silentDid both filters match?Add logging inside an unstarted script
Hook runs on every callIs the matcher absent or broad?Make the handler faster before narrowing scope

Verbose logs shorten diagnosis but can contain sensitive operational input. Give the incident record sanitized excerpts, session context, and configuration revisions, while keeping raw diagnostics within the team’s authorized storage.

Architecture / decision scenario

A government technology team must restore its approved diagnostic workflow within 30 minutes without broadening production access. Six engineers use the same repository revision; two cannot query monitoring, and another reports that a cleanup hook never fires. The tempting fix is a shared wildcard allow and a rewritten root instruction file.

The platform owner compares /context and /status. The supposedly missing instruction is nested and loads when its directory is read. /permissions identifies a deliberate deny on deployment tools, which remains intact. /mcp reveals that one affected engineer dismissed project-server approval; the other launched from a directory that breaks a relative server-script path. Approval and an absolute path restore the query capability.

The hook appears in /hooks, but its handler has if: "Bash(rm *)" under SessionStart. The owner places it on the intended tool event, then verifies one matching and one nonmatching call in the debug log. Success means restored queries and predictable hook firing with the deployment deny preserved, not fewer permission prompts.

Common exam traps

  • Treating /memory as proof of every instruction loaded into context.
  • Treating a connected server with no tools as a prompt failure.
  • Adding an allow rule to override an effective deny.
  • Debugging a handler without checking registration and if first.
  • Treating a command hook’s exit 1 as a policy block.

What to remember

Inspect the failed session, identify the stage, and repair its responsible source. /context, /status, /permissions, /mcp, /hooks, and a debug log answer different questions. Restore intended behavior without silently changing the team’s access policy.

Knowledge check

References