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.
My sessions list is empty
Section titled “My sessions list is empty”Four different breakages produce an empty sessions list, and doctor separates them into separate checks for exactly that reason.
mossbear doctor✗ Agent hooks configured— nothing is logging. Runmossbear initin 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 PATHor a Stop hook that cannot findmossbear. 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.
My pending count never falls to zero
Section titled “My pending count never falls to zero”The hooks are logging and the sync cannot get out.
mossbear doctorLook 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 runmossbear 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:
mossbear guides activecat AGENTS.mdRead 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.
guides active is empty
Section titled “guides active is empty”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.
mossbear doctor --dashboard-url https://app.mossbear.ioDoctor 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.
mossbear login says nothing changed
Section titled “mossbear login says nothing changed”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.
mossbear login didn’t open my browser
Section titled “mossbear login didn’t open my browser”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:
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.
I unlinked a guide and it keeps arriving
Section titled “I unlinked a guide and it keeps arriving”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.
Nothing is wrong and I want less of it
Section titled “Nothing is wrong and I want less of it”mossbear narration off stops this repo from syncing redacted transcript excerpts with
its actions. Run it with no argument to see the current setting.
mossbear narrationThe 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.