When something goes wrong with pi-napkin, the best starting point is the vault and the distill error directory. Most issues fall into one of the categories below — find the symptom that matches yours, expand it, and follow the steps. For anything that requires inspecting distill subprocess state, the Diagnostic Commands section at the bottom has quick copy-paste one-liners.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-napkin/llms.txt
Use this file to discover all available pages before exploring further.
"No vault in cwd"
"No vault in cwd"
Some command or tool couldn’t resolve a vault from the current directory. pi-napkin (and the This prints the resolved
napkin CLI) walks up from cwd looking for a .napkin/ config subdir. If that walk finds nothing, it falls back to the global config at ~/.config/napkin/config.json. If that’s also missing, vault resolution fails with this message.Solutions:- Run from inside a vault. Any ancestor directory containing
.napkin/(or.obsidian/) will satisfy vault resolution — you don’t need to be at the vault root itself. - Set the global fallback. Create (or edit)
~/.config/napkin/config.json: - Pass
--vaultexplicitly. Everynapkinsubcommand accepts a--vault <path>flag to bypass resolution entirely.
configPath and contentPath. If it errors or points at the wrong directory, one of the three fixes above is needed.Auto-distill stopped working
Auto-distill stopped working
Auto-distill silently stops scheduling new runs when the background state becomes inconsistent — most commonly because a previous pi process crashed mid-distill and left a stale worktree entry behind.Step 1 — Check for stale worktrees:
Run This is safe to run at any time. Anything valuable is either already committed to the vault’s default branch or was never going to commit. The cache only holds ephemeral worktree state.After clearing, open a new pi session and auto-distill will re-arm on the next
/distill-status in your pi session. If you see entries marked (dead), those are the culprits. The next session start will sweep them automatically via cleanupStaleWorktrees, so simply restarting pi often fixes this.Step 2 — Nuke the per-vault cache:
If restarting doesn’t help, delete the cached state for the affected vault:session_start.Distill keeps failing (`failed:<reason>`)
Distill keeps failing (`failed:<reason>`)
Each failed distill writes two files into
<vault>/.napkin/distill/errors/:- Outcome sidecar:
<ISO-timestamp>-<pid>-<branch-hash>.outcome— first line is the machine-readable class (failed:<reason>); remaining lines are a human-readable recovery hint pointing at the exact command to run. - Error log:
<ISO-timestamp>-<pid>-<branch-hash>.log— wrapper diagnostics plus the agent’s stderr.
| Symptom | Cause | Fix |
|---|---|---|
agent-timeout recurring | Distill is taking longer than distill.maxDurationMinutes (default 10) | Bump distill.maxDurationMinutes in .napkin/config.json, or check the .log file to see what the agent was doing when it was killed |
markers-after-agent-exit | The agent left unresolved conflict markers in a tracked *.md file; the squash commit may already be on the default branch | Run git revert HEAD --no-edit in the vault to undo the corrupt commit cleanly. Content is recoverable from git reflog for ~90 days |
agent-exit-nonzero | The pi -p subprocess exited non-zero | Check your model provider (rate limits, auth refresh, network). The agent’s full stderr is in the companion .log file |
divergent-history | A teammate pushed to origin/<default> while this distill was running, so local and remote diverged | Run git pull --no-rebase in the vault to integrate, then let the next distill run normally |
pre-existing-markers | Conflict markers were already in the vault before this distill ran — the agent didn’t introduce them | Find the files listed in the .log, resolve the markers by hand, commit, then re-run distill |
head-not-on-default | The vault HEAD ended up on the wrong branch after the agent exited | Run git checkout <default-branch> in the vault, confirm nothing is in flight, then re-run distill |
internal-validator-error | The wrapper’s post-distill marker validator could not run (e.g. mktemp failed due to a full disk or locked TMPDIR), so the vault was never scanned after the agent exited | Inspect the vault manually for unresolved <<<<<<< / ======= / >>>>>>> markers before relying on the squash commit. If clean, the squash is keepable; otherwise git revert HEAD --no-edit. Content is recoverable from git reflog for ~90 days |
The outcome sidecar’s recovery hint is always specific to the failure. It names the exact
git revert SHA or git reflog command rather than generic advice — read it before reaching for a nuclear option."vault not a git repo" / "legacy embedded layout"
"vault not a git repo" / "legacy embedded layout"
Auto-distill has two hard prerequisites: git and the subdir vault layout (Verify with
.napkin/config.json in a .napkin/ subdirectory, distinct from the notes root). If either is missing you’ll see one of these errors.vault not a git repo:Three options — pick any one:- Set
distill.enabled: truein.napkin/config.jsonand let pi-napkin auto-init git on the nextsession_start. It will rungit init, scaffold the managed.gitignoreblock, and make an initial commit. - Run
git initin the vault root yourself, then start pi. - Opt out entirely: set
distill.enabled: falsein.napkin/config.json.
/distill does not require git — it falls back to a tmpdir spawn. Only auto-distill (interval + shutdown) needs git.legacy embedded layout:This means your vault has config.json directly at the vault root (where configPath === contentPath), with no .napkin/ subdirectory. Auto-distill needs the subdir layout for worktree-based concurrency to be safe.Auto-distill is disabled for the session, but manual /distill continues to work regardless.Follow the vault migration steps to move to the subdir layout. The migration is a three-step file move:napkin vault --json — the path field should point at <vault>/.napkin/.Status bar shows `distill: off` even though enabled
Status bar shows `distill: off` even though enabled
The status bar shows The old location Check 2 — Vault resolution:Confirm pi is loading the config you edited:The If suppressed, re-enable with
distill: off when distill.enabled is false (or absent) in the vault config that pi actually loaded.Check 1 — Correct config location:The config must be in .napkin/config.json inside your vault:~/.pi/agent/napkin.json is no longer read. If you’re coming from an older pi-napkin install, migrate:path field shows which .napkin/ directory was resolved. If it points somewhere unexpected, check the vault resolution order (local .napkin/ → global ~/.config/napkin/config.json).Check 3 — Session suppression:The status shows distill: off (session) when the timer has been suppressed for this specific session via /distill-auto-this-session off. Check current state:/distill-auto-this-session on.Distill ran but produced nothing (`no-content`)
Distill ran but produced nothing (`no-content`)
A
no-content outcome is a valid no-op — not an error. The distill agent deliberately skips sessions with nothing worth capturing.The distill prompt instructs the agent to be selective: only extract knowledge useful to someone working on the project later. It explicitly skips meta-discussion, tool output, chatter, and sessions that are purely operational (running commands, browsing files) with no conceptual content.What to check:- Does the session contain real knowledge content — decisions, explanations, solutions, discoveries — or was it mostly tool invocations and back-and-forth?
- If you believe there was content worth capturing, you can trigger a manual distill immediately:
This bypasses the size-dedup check and re-runs the full distill pipeline against the current session.
no-content surfaces as a warning in the status bar (⚠) rather than an error (✗) precisely because it’s an expected outcome for short or operational sessions.`config.json` is not valid JSON error
`config.json` is not valid JSON error
If pi-napkin surfaces Alternatively, paste the file contents into an online JSON validator such as jsonlint.com.After fixing, restart pi (or
config.json is not valid JSON, it means .napkin/config.json has a syntax error that prevents parsing. pi-napkin refuses to guess the intended shape — auto-distill is disabled for the session until the file is fixed.Fix it by hand:Common JSON mistakes:- Trailing commas after the last item in an object or array
- Unquoted string values (all strings must be in double quotes)
- Missing closing braces or brackets
- Single-quoted strings instead of double-quoted
/quit and reopen the session). pi-napkin re-reads the config on every session_start.