1. Stale index after a pull, rename, or schema change
Symptom. Commands return symbols that don't
exist anymore, miss new ones, or report a verdict that doesn't
match the working tree. Often happens after git pull
on a long-lived branch, after a large rename, or after upgrading
Roam to a version that changed the SQLite schema.
Diagnose.
roam doctor reports stale-index status; the
schema-version check tells you if the DB is older than the
installed roam-code version.
Fix. Refresh the index. Normal indexing also refreshes Git metadata after a commit whose file contents were already indexed. Use a forced rebuild for damaged derived data or a requested full refresh.
$ roam index $ roam doctor # Full rebuild, if needed: $ roam index --force
Doctor exits 0 for advisory-only results and 2 for blocking failures.
roam doctor --strict also exits 2 on advisory failures.
Review the named check: template drift and changed manifest inputs
can reflect intentional configuration, while a missing or incomplete
index requires recovery.
2. Database locks and cloud-sync conflicts
Symptom. Random
database is locked errors, partial writes,
ghost conflict copies of .roam/index.db,
or commands hanging on the first SQLite open. Another indexer,
watcher, database tool, or file-sync client may hold the database.
Diagnose. Check for an active writer using this
checkout, run roam doctor, and check whether the project lives
inside a synced folder. On macOS / Windows the path will
contain iCloud Drive, OneDrive, or
Dropbox.
Fix. Let the active writer finish or stop it normally,
then retry roam index. Keep the checkout on a local,
writable filesystem outside cloud-sync folders. A forced rebuild
cannot bypass a live SQLite writer lock.
If Roam reports that an index lifecycle owner is live or cannot be
proven stale, preserve .roam/index.lock and the lifecycle
marker while investigating the owner. Roam recovers proven abandoned
generations itself. Deleting ownership records can allow conflicting
writers to run against the same index.
Choose the store and build policy.
ROAM_DB_DIR or roam config --set-db-dir
keeps the database, index.lock, and index.state
together in the selected directory. Other configuration and evidence
artifacts remain project-local. Stop older indexers before upgrading
or changing store locations; do not mix writer versions on one store.
Set ROAM_NO_AUTO_INDEX=1 to refuse implicit builds with
exit 3. JSON mode distinguishes a missing index from an
incomplete one without opening it. Run roam index
explicitly to build or recover it. roam init also builds,
and intentionally creates project configuration.
3. Missing optional extras
Symptom. An ImportError on
startup, or a "feature unavailable — install
roam-code[X]" warning. Roam keeps the base
install small and gates heavy dependencies behind extras.
Diagnose.
roam doctor lists which extras are installed and
which features are gated off.
Fix. Install the extra you need.
# MCP server (FastMCP) $ pip install "roam-code[mcp]" # Semantic search (onnxruntime) $ pip install "roam-code[semantic]" # CLI file watcher (built-in polling) $ roam watch # no extra dependency required # MCP reactive watcher (optional watchdog dependency) $ pip install watchdog $ ROAM_MCP_WATCH=1 roam mcp
4. Parser failures — zero symbols extracted from a file
Symptom. A file you know exists is missing
from roam search results, or
roam file <path> returns an empty skeleton.
Usually a tree-sitter grammar load failure. On a fresh environment,
first use may need tree-sitter-language-pack to populate
its user cache. Roam pins a release that coordinates concurrent
first-use loads and publishes cache files atomically. A persistent
failure usually means acquisition is unavailable, the cache is not
writable, or the install is incompatible. An unsupported extension is
different: Roam skips that unavailable grammar (or uses a documented
regex fallback) without attempting a download.
Diagnose.
roam doctor reports the installed parser packages and
parser-version drift recorded by the last index. Run
roam index --force for an end-to-end grammar check.
Fix a supported grammar. Reinstall the exact Roam release so its tested grammar-pack range remains authoritative, confirm that the first-use download can reach its documented public destination and that the user cache is writable, then rebuild the index. Reinstalling cannot add an unsupported grammar; for that case, use a supported file type or add a language extractor before rebuilding.
$ pip install --force-reinstall "roam-code==14.0.4" $ roam doctor $ roam index --force
In a roam-code source checkout, use the locked development environment:
uv sync --locked --no-default-groups --extra dev --group ci --python 3.12 --reinstall-package tree-sitter-language-pack.
Stop the MCP server or watcher using that environment before replacing
a loaded native parser library, then restart the integration.
5. Agent doesn't see Roam's MCP tools
Symptom. Claude Code, Cursor, Codex, or your own MCP-aware agent has Roam configured but doesn't list the Roam tools when you ask it. Usually the MCP server isn't starting, the binary isn't on the agent's PATH, or the editor's MCP config points at the wrong working directory.
Diagnose. Run the server directly. If it starts and lists tools, the problem is the editor's config.
$ roam mcp --list-tools $ which roam # path the editor needs
In PowerShell, use Get-Command roam to inspect the executable path.
Fix. See the per-editor walkthrough in
/docs/integration-tutorials
— it covers Claude Code, Cursor, Codex CLI, Gemini CLI, and Amp.
The common gotcha: the editor MCP config must use the absolute
path to roam, not the bare command, when running
inside a sandboxed launcher.
6. Cache or DB permission errors
Symptom.
PermissionError on .roam/index.db,
.pytest_cache/, or ~/.cache/roam/.
Usually because a previous run was launched as a different
user (root via sudo, a CI runner UID, a Docker
container) and left files the current user can't write.
Diagnose.
ls -la .roam/ on Unix or
icacls .roam on Windows shows the owner.
Fix. Restore access for the account running Roam. Confirm ownership of the affected paths before changing permissions.
# macOS / Linux $ sudo chown -R "$(whoami)" .roam .pytest_cache
Preserve project state before a reset. .roam/ contains
rules, annotations, memory, signed run ledgers, keys, and proof bundles
as well as the rebuildable index. Fixing permissions or running
roam index --force after writers stop avoids deleting that state.
7. Out-of-memory during indexing on a large monorepo
Symptom. Indexer is OOM-killed on a repo with hundreds of thousands of files, or RAM climbs past available and the process slows to a crawl. Roam parses the working set in-memory before flushing to SQLite; very large monorepos can exceed reasonable RAM budgets.
Diagnose.
Inspect process memory while indexing and use roam index-stats
to inspect an existing index. Review which generated and vendored files
are included; roam doctor checks environment and index
readiness but does not predict peak indexing memory.
Fix. Exclude what you don't need to index —
generated code, vendored dependencies, large fixtures — via
a .roamignore file at the repo root (gitignore
syntax). Then force a clean rebuild.
$ echo 'vendor/' >> .roamignore $ echo 'generated/' >> .roamignore $ roam index --force
8. --json output is too verbose / too slow
Symptom. Piping
roam <cmd> --json into an agent's context
uses too many tokens, or the envelope wrapper makes
line-oriented parsing awkward.
Diagnose.
roam <cmd> --json | wc -c gives you the
byte count. If the envelope is bigger than the payload, you
want compact mode.
Fix. Use --compact for narrower
envelopes (drops _meta, schema preamble, and
optional fields).
$ roam impact AuthService --json --compact $ roam preflight AuthService --json --compact
Still stuck?
Email hello@roam-code.com
with the output of roam doctor --json attached.
That dump tells us your roam-code version, Python version,
installed extras, schema version, language coverage, and
index health — usually enough to identify the issue without a
back-and-forth.
$ roam doctor --json > roam-doctor.json
For bug reports, file an issue at github.com/Cranot/roam-code with the same dump attached.
See it run:
The 5-minute canonical demo —
install → health → preflight → critique → signed
ChangeEvidence packet, end to end. If you can run this
on a clean venv, your install is healthy.
Related docs: Getting Started for the first-run path, Using Roam via MCP for agent / editor setup, Command Reference for the full CLI surface.