Are you TokenMaxxing hard enough? Find out in less than a minute →

Troubleshooting

Run tj doctor, read its exit codes, and fix the common daemon-lock, schema, capture, and MCP issues.

Most problems surface the same way: a blank dashboard, a command that hangs, or costs that don’t add up. Start with tj doctor, then work through the specific issues below.

tj doctor

tj doctor runs a battery of health checks and prints a status line for each one.

tj doctor

It checks:

  • Config file: that it exists, parses as valid TOML, and has no conflicting overrides.
  • DuckDB writable: that the database file can be opened. When the daemon is running it holds the write lock, so this check downgrades to “skipped” rather than failing (that’s the expected state after tj onboard).
  • Schema vs capture: flags an agent that declares an output_schema while capture.tool_outputs is false, since validation would have no data.
  • Drift readiness: reports how close each agent is to its drift baseline threshold.
  • Webhook security: checks alert webhook URLs and the domain allowlist.
  • Span stats and staleness: surfaces an empty or stale database (no recent spans).
  • Schema integrity: detects a migration recorded as applied whose column never actually landed (see schema self-heal below).
  • Onboarding first signal: confirms tj has seen at least one span since setup.

Exit codes

tj doctor sets its exit code so you can gate on it in scripts:

CodeMeaning
0Healthy. Everything passed.
1Warnings. Nothing broken, but something worth a look.
2Errors. At least one check failed.

Add --json for machine-readable output, and --repair to attempt fixes for any issue that has a known repair path.

The daemon holds the DB lock

DuckDB is single-writer. Only one process can open the database for writing at a time, and a running tj serve claims that lock. This blocks other tj commands that need write access, and can even block read-only opens.

Symptoms are a hanging command or an error mentioning a conflicting lock on ~/.tj/telemetry.duckdb.

The fix is to stop the daemon before running a command that needs direct database access:

tj stop

tj stop halts the background daemon and sweeps any stray foreground tj serve process, freeing port 7391. Restart the daemon afterward with tj serve (or let the next login start it).

Many commands avoid this entirely. When tj serve is up, commands like tj optimize and tj cost fall back to the daemon’s HTTP API instead of opening the database directly, so they keep working without a stop.

Blank Status page (schema self-heal)

A blank Status page usually means spans are being dropped on write. This happens when a database migration was recorded as applied but its ADD COLUMN never landed, so every ingest that writes the missing column fails silently.

tj doctor catches this under its Schema integrity check. Fix it with:

tj doctor --repair

The repair rebuilds the affected table. Your data is preserved. tj also re-issues the additive column definitions on every open, so the gap normally heals itself before you notice it.

Costs or content look wrong

If prompts, completions, or tool outputs aren’t showing up where you expect, check your capture toggles. By default tj records only metadata (tokens, cost, latency, span structure) and stores no text.

[capture]
prompts      = true
completions  = true
tool_outputs = true

Flip the flag for the content you want captured, then restart tj serve to pick up the change. Captured text only ever lives on your machine. See Configuration for the full list of toggles.

MCP server won’t connect

tj mcp chooses its connection mode at startup, and each mode changes what data the tools can see:

  1. Proxy to the daemon. If tj serve is reachable, tj mcp proxies to it over HTTP and sees live ingest as it happens. This is the best case.
  2. Spawn the daemon. If no daemon is running, tj mcp tries to start tj serve in the background and waits up to ten seconds for the port.
  3. Read-only fallback. If it can’t reach or start a daemon, it opens the DuckDB file directly, read-only. The read tools still work, but spans ingested after startup won’t appear until you restart.
  4. No config. If no config file is found, the tools return a no-config sentinel. Run tj onboard first.

If your MCP tools show stale data, you’re likely in the read-only fallback. Start tj serve first, then restart the MCP client so tj mcp proxies to the live daemon.

Still stuck?

Run tj doctor --json and include the output when you file an issue. It captures the config, database, and schema state in one shot, which is usually enough to pin down the problem.

Get TokenJam updates