Skip to content

Troubleshooting

Start with mossbear doctor. It prints one line per check, and a failing check always prints its remedy with it. The sections below are for when doctor is clean and something is still wrong, or when you want to know which of two checks is the one that matters.

Read them by symptom. Several of these failures report success, which is why the command that tells them apart is named in each one.

Four different breakages produce an empty sessions list, and doctor separates them into separate checks for exactly that reason.

Terminal window
mossbear doctor
  • ✗ Agent hooks configured — nothing is logging. Run mossbear init in the project.
  • ✗ Failed tool calls logged (PostToolUseFailure) — successful tool calls reach the grader and failing ones do not. A failing Bash exit, a denied edit and an erroring MCP call all dispatch through that second event, so without it every failure is invisible.
  • ✗ Session uploads to the dashboard — this is the dangerous one. Actions are being logged to ~/.mossbear/runs/ and never uploaded. Everything looks wired up locally, and on a container destroyed at session end the whole record goes with it.
  • ✗ mossbear-hook on PATH or a Stop hook that cannot find mossbear. Configured is not the same as able to run. The hook binary and the CLI are two different bins, so a partial global install satisfies one check while every upload dies as command-not-found. Reinstall globally: npm install -g mossbear.

A fifth case reports nothing at all: your agent never had hooks to begin with. mossbear init writes hooks for the harnesses it has a writer for, and Cursor has no lifecycle hooks at all. Antigravity CLI does get a writer, but you have to ask for it — mossbear init --platform antigravity — because a .agents/ directory is not evidence you use it. See local agents for which agents get which half of the loop.

The hooks are logging and the sync cannot get out.

Terminal window
mossbear doctor

Look at the Dashboard connection line, which is informational and never fails the run:

  • token rejected — the token is expired or revoked. Get a fresh one from Settings → Machines and run mossbear refresh --token <token>.
  • refused with 403 by something between this machine and the dashboard — the token was not rejected. Something in between refused the request, and in a managed cloud environment that is an egress proxy enforcing a host allowlist. Add your dashboard host to it. Doctor names the proxy variable it found set, and prints the name only, because a proxy URL can carry credentials in it.
  • could not reach — a proxy that refuses the tunnel outright surfaces this way rather than as a 403. Same fix.

mossbear status shows the queue itself. Pending actions are the ones logged since the last successful upload.

guides active lists a guide that never reached disk

Section titled “guides active lists a guide that never reached disk”

mossbear guides active reads the cached bundle your last sync pulled from the dashboard. It is not a reading of your working tree. So a guide the dashboard sent appears there while the file it names stays absent, and the two commands disagree by design:

Terminal window
mossbear guides active
cat AGENTS.md

Read them in that order and do not let the first stand in for the second.

A repo receives guides by subscribing to the bundles they are in, and mossbear refresh materializes them. So the fix is usually one refresh, or a mossbear pull <bundle> to subscribe to a bundle this repo was not subscribed to.

Some guides can never reach disk at all. guides active counts those separately: a guide with no file to be written back to has no destination, so no number of syncs will produce one.

The pull never reached the dashboard. That is a different failure from the one above, and the empty list is the tell. Check the log of whatever ran the pull, and confirm the token was stored on this environment rather than another one.

The token was minted on the wrong dashboard

Section titled “The token was minted on the wrong dashboard”

Staging and production have separate databases, so a production token is not valid on staging. A token minted on the wrong one comes back as token rejected, which reads identically to an expired token.

Terminal window
mossbear doctor --dashboard-url https://app.mossbear.io

Doctor prints the dashboard URL it probed in the same line as the verdict, so pointing it at each in turn tells you which one the token belongs to. mossbear doctor also names the source when the token came from $MOSSBEAR_TOKEN rather than ~/.mossbear/config.json, because in an ephemeral container “which token is this?” is the first question a failed sync raises and an environment variable leaves nothing to inspect.

If MOSSBEAR_TOKEN is set in your environment, login makes no change and says so. The environment owns that credential, and a config token written underneath it would be ignored on every later read, which would leave you looking at “paired” while every command kept using the old one. Unset the variable and run login again to pair a different account.

If login is waiting and nobody is at the terminal to approve it, --print-url puts the approval URL and code on their own lines and keeps polling. That mode is automatic when stdout is not a TTY, so an agent running login can hand the URL to a person and still be holding the connection when they approve.

Login opens the approval page itself only when someone is at the terminal — not with --print-url, not when stdout is not a TTY, not on a Linux machine with no DISPLAY or WAYLAND_DISPLAY set, and not when BROWSER=none. It also cannot see whether the launcher it started (open, xdg-open, wslview, rundll32) succeeded. The approval URL is printed above the wait either way — open that, and login is still holding the connection when you approve. --no-open skips the launch entirely.

A synced artifact reports as missing after I moved it

Section titled “A synced artifact reports as missing after I moved it”

mossbear refresh names the path it expected. Point the mapping at where the file lives now:

Terminal window
mossbear artifacts relink <old-path> <new-path>

It refuses, and exits non-zero, rather than adopting a file that is not the one it was tracking.

mossbear unlink removes the membership mossbear link created, in the default bundle. A guide someone deliberately added to a curated bundle is a second membership, and it keeps delivering. The command names those rather than reporting a clean unlink.

mossbear narration off stops this repo from syncing redacted transcript excerpts with its actions. Run it with no argument to see the current setting.

Terminal window
mossbear narration

The setting is keyed by a one-way digest of the repo, so this command is the only way to write it. If the opt-out list in your config is not a list of repo ids, narration is off everywhere until you fix it, and the command refuses to overwrite the malformed value rather than replacing your file.

To see what leaves your machine before deciding how much to turn off, run mossbear what-syncs. Every other command on this page is in the CLI reference.