Docs · troubleshooting

When it says no,
it is usually right.

Most of what looks like a bug is the brain refusing to guess. Each refusal below says what it protects. If you don't know why a guard is there you will find a way around it and getting around these is how memories get lost.

Run these first #

$ ns-brain env       # every resolved path, the project name, git, the clock
$ ns-brain stats     # counts and the database path on line two
$ ns-brain doctor    # dangling links, cycles, index drift
$ ns-brain version   # and compare against the brief's version line

Together those four answer almost every "it is not doing what I expected": which file, which project, which build and whether the brain is in good shape.

The brief did not appear at session start #

First check the command works, then check the hook does. They break in different ways.

$ ns-brain wakeup

An agent that cannot run shell commands has no hooks at all. The MCP page says what an agent without hooks gives up.

Recall returns nothing #

This is on purpose. When a script searches (recall --json) and nothing matches, it gets nothing back, not the closest thing or everything in the scope. Try these, in order:

Wrong store, wrong project #

SymptomWhat it is
0 memories in a brain you know has someRight command, wrong file. ns-brain stats prints the path. Anything looking at the shared store can't see a project that has its own file. It works the other way round too.
Memories filed under another project's nameSomething named the wrong project over MCP. ns-brain relabel <label> --expect <n> --apply moves them back.
"cannot tell which project you are working in"A shared store and nothing says which project this is. Set BRAIN_PROJECT, the X-Brain-Project header or _project. The MCP page lists the three ways to name a project, best first.
An id that exists and cannot be readIt belongs to another project. Leave them a note. Don't reach in.
Phantom projects in the indexSomething meant for a scratch directory ran against your real one. For anything throwaway, set CLAUDE_CONFIG_DIR and BRAIN_GLOBAL_DB to scratch paths.

Refusals and what each one protects #

RefusalWhat it protects you fromHow to get past it
"#42 is already about this"Two answers to one question in one scope. That is worse than one answer that admits it doesn't know.--supersedes 42, update 42 or --allow-duplicate
forget refuses a pinned memory or a guardrailA session deleting a rule because it got in the way.--force, deliberately
forget refuses a memory that supersedes othersDeleting it would bring back the old facts it replaced on purpose.Supersede it with a correct version instead, or --force to accept the old facts coming back
prune refuses tier A or BThe tiers that never fade hold the facts that are hardest to work out again.--i-mean-it, after reading the dump it took
prune refuses a same-day cutoffAn --older-than 0 that means "everything".Pick a real cutoff
export or snapshot refuses to overwriteOverwriting a file this tool didn't make, which is somebody's work.--force, or write elsewhere
refuses a git-tracked pathA full copy of the brain committed to a repository forever.--allow-tracked if you truly mean it
"this looks like a credential"A token in a memory, which then sits in every backup, snapshot and export.--allow-secret when it is a false positive
update refuses an empty bodyWiping a memory by accident. A failed shell substitution once blanked a tier-A memory and said it worked.--force

What doctor finds #

$ ns-brain doctor
$ ns-brain doctor --fix   # repairs the repairable, names the rest

In a shared store doctor checks the whole file, not just your project, because a fault in another project's memories is still a fault in the database you use. It shows counts and ids, never titles or bodies.

Search index and upgrades #

Database upgrades only add, run as one step and are undone completely on any error. If one fails, the database is left as it was and the error names the version it was upgrading to. A database newer than the binary opens only if it says this binary can read it safely. If not, the binary refuses and tells you the upgrade command to run.

Both upgrade bugs we have found so far only showed up on an old database, never a new one. So our tests upgrade a real old database through every version in between.

If a brain won't open after an upgrade, don't try fixes of your own. You have a backup, because upgrade --apply makes one first. ns-brain backup --list --verify lists the safety copies and checks each one can be read. backup --restore <file> puts one back. It only shows what it would do until you add --apply.

Reporting a bug #

If you are an agent in a project with a brain, the axiom applies: report the bug. Don't fix the tool yourself and don't quietly work around it. A bug one project hides is one every other project will hit.

Report it from the command line. The first time, you register the machine with a six-digit code sent to your email.

$ ns-brain feedback register you@example.com   # local brain, once
$ ns-brain feedback verify <code>
$ ns-brain feedback "recall --json returns an empty envelope for a title I can get by id"
$ ns-brain feedback - < report.txt   # a longer report, from stdin

That goes to the people who maintain ns-brain. Your version and OS are added for you. Your brief tells you when a reply arrives and ns-brain feedback list shows it. Include the exact command and what you expected. A report that looks like it contains a password or key is refused, just as remember refuses one.

Security issues go by email instead, to security@fightclub.pro.