Reference
Troubleshooting
When you see error X, here's what triggered it and how to fix it. Every error string on this page is grounded against a real source location. If the binary says something word-for-word different, that's the bug, please file it.
1. repository not found at <path>
Where: any command that opens a repository
(capture, log, show, status). The CLI walked up from the
current directory looking for a .heddle/ directory and didn't find one.
Fix: run heddle init at the
repo root, or cd into a directory inside an
existing Heddle repo.
$ cd path/to/project
$ heddle init Source: crates/objects/src/error.rs:15
2. Virtualized workspace requires Linux/macOS/Windows + heddle built with --features mount
Where: heddle daemon serve, or heddle start --workspace virtualized — anything that
mounts. The binary you're running was built without the mount feature flag. Virtualized workspaces are supported across
Linux (FUSE), macOS (FSKit), and Windows (ProjFS); the
feature just has to be compiled in.
Fix: rebuild with the feature enabled, or
use materialized threads (heddle start + a real
checkout) instead.
$ cargo build --release --features mount Source: crates/cli/src/cli/commands/mount_lifecycle.rs:116
3. No current thread
Where: heddle capture --split invoked outside a thread checkout. The recovery advice reads "Run heddle capture --split from an active
thread checkout, or retry with heddle thread switch
<name> to choose a thread explicitly." Splitting moves dirty paths into another thread, which only
makes sense when you've taken responsibility for a thread.
Fix: start or switch to a thread first, then
re-run capture --split, naming the target thread
with --into and each prefix with --path.
$ heddle start "task/biscuit-authz"
$ heddle capture --split --into "task/auth-tests" --path src/auth --path tests/auth Source: crates/cli/src/cli/commands/thread_shaping.rs:78
4. No dirty paths matched the requested split prefixes
Where: heddle capture --split --path
<prefix> when the worktree is dirty under some
other path. Splitting only operates on paths that actually
have pending changes; a prefix that no dirty file lives under
produces nothing to move into the target thread and is
treated as a user error rather than a silent no-op.
Fix: run heddle status to see
which paths are dirty, then re-run with a --path prefix that matches one of them.
$ heddle status
$ heddle capture --split --into "task/side" --path <a-prefix-from-status> Source: crates/cli/src/cli/commands/thread_shaping.rs:91
5. unrecognized subcommand 'checkpoint'
Where: anywhere you reach for heddle checkpoint, heddle switch, heddle stash, heddle merge or heddle rebase. None of them exist. ADR 0046 deliberately
declines to expose them as competing top-level verbs, so clap rejects
them with exit 64 before anything runs. Older
documents — including some of Heddle's own ADRs — still name checkpoint; the catalog is the authority.
Fix: the analogue of naming a state worth coming back
to is a marker, an immutable named reference to a state, under heddle thread marker. There has to be a state to name, so
capture first.
$ heddle capture -m "initial"
$ heddle thread marker create pre-refactor
$ heddle thread marker list Source: docs/adr/0046; the 192-command catalog contains no checkpoint.
6. hook install requires --from-file <path> or stdin input
Where: heddle hook install called interactively with neither --from-file nor a piped script. The companion error hook install received empty stdin; pass --from-file
<path> or pipe script content fires when stdin
is open but empty.
Fix: pass the script as a file, or pipe its contents.
$ heddle hook install pre-snapshot --from-file ./hooks/lint.sh
# or
$ cat ./hooks/lint.sh | heddle hook install pre-snapshot --from-stdin Source: crates/cli/src/cli/commands/hook.rs:143
7. state '<id>' not found
Where: heddle redact apply with
a state spec the resolver couldn't match. The state argument
accepts short or full state IDs, marker names, HEAD, @, or HEAD~N. If
none of those resolve, you get this error.
Fix: resolve the state spec first via heddle log or heddle show, and pass the hd- change ID — or an unambiguous prefix of one.
The trap: the parenthesised value printed beside it is
a BLAKE3 content hash, and it is not a command argument.
Neither is the Git checkpoint sha on the Git checkpoint: line. Three ids appear in history output and they are not
interchangeable: hand hd-… change ids to Heddle, the
checkpoint sha to a Git-compatible client, and the content hash to
neither — it is for integrity and equality checks only.
A second trap sits behind the first: an hd-… is not a lineage handle. Amending or rebasing produces a new state with a new hd-…, so an id
captured before a rewrite still resolves to the pre-rewrite state. An
agent that caches one across a rebase silently operates on the old
thing.
$ heddle log
$ heddle redact apply hd-qrvnt3yr1vt6 --path src/leaked.rs --reason "rotated" Source: crates/cli/src/cli/commands/redact.rs:492
8. path '<p>' not in state <id>
Where: heddle redact apply
<state> --path <p> when the path doesn't
exist in that state's tree. The redactor refuses to write a
redaction marker for a file that was never there; that would
create a tombstone pointing at nothing.
Fix: inspect the state first, copy the exact path you want gone, then redact.
$ heddle show hd-qrvnt3yr1vt6
$ heddle redact apply hd-qrvnt3yr1vt6 --path crates/cli/secrets.toml --reason "rotated" Source: crates/cli/src/cli/commands/redact.rs:510
9. Repository has no HEAD state for review next
Where: heddle review next / review show on a brand-new repo where no
capture has landed yet. Review needs a concrete state to
compute against and won't infer one. The advice reads "Capture the current worktree with heddle capture
-m "...", then retry."
Fix: capture, then review.
$ heddle capture -m "initial"
$ heddle review next Source: crates/cli/src/cli/commands/review.rs:320
10. A merge is already in progress
Where: starting a second merge while the
first one still has unresolved files. Heddle keeps merge
state for the repository so the next agent can pick up where
you left off, and that record also blocks a competing merge from
racing it. The advice points you at heddle status,
then heddle continue or heddle resolve --abort.
Fix: either finish the current merge
(heddle resolve <path> for each conflict,
then heddle continue to land it), or abort.
$ heddle status # see which files are unresolved
$ heddle resolve src/auth/session.rs --ours
$ heddle continue
# or, to back out:
$ heddle resolve --abort Source: crates/cli/src/cli/commands/merge/mod.rs:389
Next
- CLI reference: every flag, grounded against the actual arg definitions.
- Operating principles: why error quality is part of the contract.
- File an issue: if an error string is misleading, that's a bug.