Skip to content

Troubleshooting

Diagnose provider coverage, MCP registration, missing memory, conflicts, and the Control Room without guessing.

health says the provider is unavailable

Check that codebase-memory-mcp is installed and on PATH. Rationale keeps working, but symbol bindings and the structural neighborhood lose coverage. The packet says so in snapshot and warnings; treat unavailable as unknown, never as complete.

If Codebase Memory lost the project it had indexed, Rationale detects the stale mapping, forgets it, and re-resolves it through the provider’s public tools on the next call.

The agent does not see Rationale’s tools

Run rationale install-agent again and restart the client. Registration is per user and uses the absolute path of the installed binary, so GUI apps work without your shell PATH. If you moved the binary, the next install-agent migrates the registration to the new path. In Claude Code, /rationale-health combines the MCP health tool with rationale doctor to show what works and what is degraded.

The agent does not use the skill

Check that rationale/SKILL.md exists under .claude/skills/ (Claude Code) or .agents/skills/ (Codex), then restart the agent so it rescans skills. Invoke it by name to confirm it loads: /rationale in Claude Code, $rationale in Codex. Automatic selection is probabilistic; the protocol in CLAUDE.md or AGENTS.md still applies when the skill is not selected. If install-agent reports that the skill directory is a symbolic link, another tool manages it and Rationale leaves it alone.

The agent answers in the wrong language

The protocol and the skill tell the agent to reply in the language you write in. Write your request in the language you want back. Identifiers, commands, and Record statements quoted from the canon stay as they are on purpose.

serve looks silent

Expected when started by hand: it waits for JSON-RPC on stdin and keeps stdout clean. Send one JSON message per line.

A candidate was discarded

Read the reason in finalize_change’s discarded list. The common ones:

  • transient or durability_not_declared — it described this change, not something that stays true;
  • rationale_restates_statement — the rationale must give the cause;
  • no_meaningful_binding — bind it to a file or symbol that exists;
  • duplicate — the same knowledge already exists under the id shown.

A Record does not appear in prepare_change

Check its bindings with rationale doctor --check: a binding to a path that no longer exists makes the Record stale for that target, and a Record without bindings cannot govern anything. Revoked and superseded Records are history, not governance.

finalize_change returned a conflict

A candidate tried to supersede a pinned Record, so it was not written. Run rationale conflicts to see both statements, then rationale resolve <conflict-id> keep-pinned|adopt-new. Only a declared actor can adopt the new assertion.

The agent wants to simplify odd code

Ask it to call explain_target first. A strange branch may be a Chesterton fence whose reason is stored in a Record.

The Control Room is empty

It shows operations and activity of this project. If RATIONALE_ACTIVITY=off was set when the agent worked, there is nothing to show. Otherwise, run a prepare_change and the graph appears within a second.

rationale ui serves an instructions page

That binary was built without the embedded interface (a source build without ui/dist). Release binaries always include it. From source: npm --prefix ui ci && npm --prefix ui run build, then rebuild.

Pre-1.0 proposals are still pending

Run rationale migrate --dry-run, then rationale migrate. Valid proposals become Records with migrated provenance; noisy ones are archived with their reason under .rationale/archive/proposals/.