Skip to main content
Common issues and solutions. For step-by-step runbooks, see the Recovery section.

Installation Issues

bd: command not found

Wrong version of bd running

If bd version shows an unexpected version (e.g., older than what you just installed), you likely have multiple bd binaries in your PATH:
This happens when a binary from an earlier go install sits in ~/go/bin/ ahead of a newer package-manager install. Choose one installation method (Homebrew recommended) and stick with it.

zsh: killed bd on macOS

CGO/SQLite compatibility issue:
Homebrew builds already enable CGO, so this shouldn’t be necessary there. If you still see crashes with the Homebrew version, please file an issue.

Permission denied

Antivirus flags bd as malware

Kaspersky, Windows Defender, and others sometimes flag bd as a generic trojan. This is a false positive — Go binaries commonly trigger antivirus heuristics. Verify the binary’s SHA256 checksum against the GitHub release page before adding an exclusion. See Antivirus False Positives for per-vendor instructions.

Database Issues

Database not found

Database locked

Do NOT remove files inside .dolt/ directories (including noms/LOCK). These are Dolt-internal files — removing them WILL cause unrecoverable data corruption. Dolt manages these files itself.
For high-concurrency scenarios (multiple agents), server mode (bd init --server) handles concurrent access natively via dolt sql-server.

bd init refuses to run

bd init and bd dolt refuse operations that could destroy local or remote history, printing a pattern code such as init-local-exists or pk-fork-refused. Each code has a runbook — see Recovery Playbooks. Export first (bd export -o backup.jsonl) if you intend to re-initialize over existing data.

Corrupted database

Distinguish logical consistency issues (ID collisions, wrong prefixes) from physical database corruption (disk failures, power loss, filesystem errors). For logical consistency issues — this is not corruption:
For physical corruption, rebuild from a Dolt remote or a backup:
See Database Corruption for the full runbook.

Dolt journal corruption after restart

Symptom (server mode): After a system restart, bd reports that the Dolt server started but is not accepting connections, and .beads/dolt-server.log contains:
Cause: Dolt detected damaged journal blocks after an unclean shutdown. This is not the same as a stale PID, stale port, or stale lock file. bd will not run Dolt’s data-loss repair mode automatically. Safe recovery when your remote is current:
If the remote may be stale, keep the corrupt directory for forensics and inspect it with dolt fsck before considering dolt fsck --revive-journal-with-data-loss. Only use the revive path after reviewing Dolt’s data-loss warning.

failed to import: issue already exists

You’re trying to bootstrap a database with issues that conflict with existing ones. Clear the local database and re-initialize from an export:

Imported children whose parent is gone

Bootstrapping from JSONL or pulling hierarchical issues (e.g., bd-abc.1) can land children whose parent bd-abc no longer exists — typically after bd delete on a parent, a branch merge where one side deleted it, or an incomplete import. Import accepts these orphans rather than failing, so the children still arrive and stay usable. Recreate the parent (or close out the orphaned children) once the import finishes. Prevention: use bd delete --cascade to also delete children, and review children first with bd children <parent-id>.

Old data returns after reset

bd admin reset --force only removes local beads data. Old issues can return from configured Dolt remotes or from other machines that push after you reset. For a complete clean slate, reset every clone (or clear the remote’s beads data) before re-running bd init. If you previously used the removed legacy sync-branch feature, also delete its branch and worktrees — see Worktrees: Legacy Cleanup.

bd shows 0 issues but the database has data

Symptom (server mode): All bd commands return empty results even though your data exists. Cause: bd is connecting to a different Dolt server or database than expected — an empty “shadow” database on the wrong server. Diagnosis:
Fix: ensure your Dolt server is running from the correct data directory and that metadata.json points at the right server and port. If a stale .beads/dolt/ directory exists alongside an external-server configuration, it can shadow the real database — confirm your real data lives on the server before removing the stale directory.

Configured server unreachable (auto-start disabled)

Symptom (server mode): bd returns “database not found on Dolt server” when the configured server is down. Cause: When metadata.json has an explicit dolt_server_port, bd treats the server as externally managed and intentionally disables auto-start — spawning a different server would create a shadow database. Fix:
If you want auto-start behavior, remove dolt_server_port from .beads/metadata.json.

Port conflicts with multiple projects

Symptom (server mode): Commands in a second project fail or connect to the wrong database, and multiple dolt sql-server processes are running. Cause: Each server-mode project starts its own Dolt server by default, which can conflict on machines with many projects. Fix: Enable shared server mode so all projects use a single Dolt server:
After enabling, existing projects may need bd init --reinit-local -q to create their database on the shared server. Verify: bd dolt status from any project should show the same server, port 3308, and ~/.beads/shared-server/ as the data directory.

Multiple databases detected warning

bd warns when it finds more than one .beads directory in your directory hierarchy, marking the one in use with (usually the closest to your current directory). Multiple databases risk working in the wrong one or tracking the same work twice.
  • Nested projects (intentional): this is supported — just note which database is active, or pin it explicitly.
  • Accidental duplicates: export from the unwanted database (bd export -o issue-export.jsonl), then remove its .beads directory.
  • Override selection:

Circuit breaker: “server appears down, failing fast”

Symptom (server mode): Every bd command fails with dolt circuit breaker is open: server appears down, failing fast (cooldown 30s), persisting across repeated invocations. Cause: The circuit breaker tripped after repeated connection failures. Its state lives in a file under /tmp/beads-circuit/ (named beads-dolt-circuit-<host>-<port>[-<db>].json, keyed on host:port) and is shared across all bd processes. Once tripped, all commands to that host:port are rejected until a successful probe resets it. For beads-managed local servers, bd dolt status reports from the server’s PID file — a “running” status does not guarantee the server is actually accepting connections on the expected port. Diagnosis:
Fix:
On macOS, /tmp is a symlink to /private/tmp, which is not always cleared on restart — the state file can persist across reboots.

Dolt Server Issues

Server not starting

Version mismatch

After upgrading bd:
Managed proxied-server mode spawns an external dolt CLI it finds via BEADS_DOLT_BIN or PATH (in that order — see Environment Variables; a clone-local sidecar setting will slot between the two when the sidecar reader lands in contract part 2). On startup it probes that binary with dolt version and recommends dolt >= 2.0.0: the 2026-07-25 cross-version compatibility matrix found that cross-reading storage written by the beads Dolt Go module (as opposed to writing it, which older dolt CLIs can also do) requires dolt >= 2.0.0 — dolt 1.85 can serve proxied mode but cannot read storage the module wrote, and dolt 1.52.1 fails at both serving and reading. This is a warning, not a hard failure — there is deliberately no hard version floor, so an older dolt can still be used at your own risk. To resolve it, install the pinned dolt version — see Which Dolt version to install — and either update PATH or set BEADS_DOLT_BIN to the new binary’s path. Install that specific version rather than latest: 2.3.x is a newer release that satisfies this warning but carries a separate data-operation defect. The advisory repeats at most once per day, not on every command: the probe result and the warning timestamp are cached (keyed by the binary’s path, size, and mtime, in the user cache directory), so day-to-day bd use stays quiet while the reminder still resurfaces until the binary is upgraded. Upgrading or replacing the dolt binary re-probes immediately. If the probe can’t parse dolt version’s output at all (most commonly a dev/custom build with non-standard version output), that also only warns — proxied-server mode still starts, since an unparseable version means “we don’t know”, not “this is definitely broken”. A genuinely missing or broken dolt binary (not found, not executable, or the probe itself fails/times out) is a hard error, not a warning.

Sync Issues

Changes not syncing

Recovery from backup

Merge conflicts

Dolt merges at the cell level, so concurrent changes conflict only when they touch the same field of the same issue. Hash-based IDs mean different issues never collide on ID.
See Merge Conflicts for the full runbook.

Git Hook Issues

Hooks not running

Hook errors

Hook timeout kills chained pre-commit hooks

Symptom: After bd hooks install, chained pre-commit hooks (eslint, prettier, ruff, etc.) stop running, with: beads: hook 'pre-commit' timed out after 300s -- continuing without beads. Cause: The beads hook shim wraps bd hooks run with an OS-level timeout. Since bd hooks run chains to your original hook internally, the timeout covers both beads’ own work and your entire hook pipeline. Fix: Increase the timeout (default 300 seconds):
The value must be a positive whole number of seconds. Invalid values and zero warn and fall back to 300 seconds. Beads accepts timeout or gtimeout only when a successful version probe identifies GNU coreutils; native Windows timeout.exe is not compatible. If neither GNU timeout nor Perl is available, the hook warns that it is running directly without a deadline. GNU timeout sends TERM; on POSIX hosts, Perl’s alarm applies to the direct bd process. Git for Windows Perl does not guarantee that alarm across exec, so GNU coreutils is preferred there. TERM-resistant work and descendant processes are not guaranteed to stop. After upgrading from a version with the name-only timeout check, run bd hooks install once to refresh existing canonical sections.

Permission denied on git hooks

Git hooks need execute permissions:

Corrupted symlinked CLAUDE.md

Symptom: Git reports CLAUDE.md as a symlink entry (mode 120000), but the indexed blob contains multi-line Markdown instead of a one-line symlink target. On macOS this can make clones or checkouts fail. This affects repositories corrupted by older setup behavior (fixed in #4192). To repair an existing bad index entry:
Commit the mode repair after review.

”Branch already checked out” or unexpected .git/beads-worktrees/

Older beads versions created hidden git worktrees for a removed sync-branch feature; leftovers can lock branches (fatal: 'main' is already checked out at .../beads-worktrees/...). Remove them:
See Worktrees: Legacy Cleanup.

Dependency Issues

bd ready shows nothing but I have open issues

Those issues probably have open blockers:
Remember: only blocks dependencies affect ready work.

Circular dependencies

bd prevents dependency cycles, which break ready work detection:
See Circular Dependencies for the full runbook.

Dependencies not showing up

Different dependency types have different meanings — only blocks gates ready work. See Dependencies.

Performance Issues

Slow queries

Consider splitting very large projects into multiple databases:

High memory usage

If this or bd flatten stops with Error 1105 (HY000): context canceled, see Storage reclaim fails with “context canceled” below.

Storage reclaim fails with “context canceled”

bd flatten and the Dolt-history compaction in bd admin compact finish by hard-resetting main onto a temporary branch; the merge-settle path behind bd dolt pull / bd sync falls back to a hard reset when it abandons a merge. On Dolt 2.3.x a few percent of freshly created databases come up with CALL DOLT_RESET('--hard') broken for the life of the server process, so on an affected database those commands stop with:
Nothing else looks wrong — ordinary queries, commits, soft resets, CALL DOLT_CLEAN() and CALL DOLT_CHECKOUT('.') all still work — so the problem only shows up when something needs a hard reset. Confirm with the check in Which Dolt version to install, which also covers the fix: restarting dolt sql-server clears it for now, and installing the pinned Dolt version keeps it clear. This applies to server and proxied-server mode, which use the standalone dolt CLI. Embedded mode links its own Dolt engine at the version pinned in go.mod and is not affected by which dolt CLI is on your PATH.

Agent Issues

Agent creates duplicate issues

Agents may not realize an issue already exists. Prevention strategies:
  • Have agents search first: bd list --json | grep "title"
  • Label auto-created issues: bd create "..." -l auto-generated
  • Consolidate duplicates: bd duplicate <dup-id> --of <canonical-id> closes the duplicate with a reference to the canonical issue

Agent gets confused by complex dependencies

Simplify the dependency structure:

MCP server not working

See MCP Server for setup and configuration.

Sandboxed environments (Codex, Claude Code, etc.)

Sandboxes that restrict process and network permissions can prevent bd from controlling a Dolt server, causing persistent “database out of sync” errors or bd dolt stop failing with “operation not permitted”. bd auto-detects sandboxed environments and prints Sandbox detected, using direct mode. If auto-detection fails, pass the global --sandbox flag explicitly:
Sandbox mode disables Dolt auto-push so bd works without server control or network access. Sync manually once outside the sandbox:
If staleness errors persist, bd doctor --fix forces a metadata refresh (low risk — it updates tracking metadata, not issues). Background: GH#353.

Platform-Specific Issues

Windows: Path issues

Windows: Firewall blocking the Dolt server

In server mode, the Dolt server listens on loopback TCP. Allow bd.exe through Windows Firewall: Windows Security → Firewall & network protection → “Allow an app through firewall” → add bd.exe for Private networks.

Windows: Controlled Folder Access blocks bd init

Symptom: bd init hangs indefinitely with high CPU usage, and CTRL+C doesn’t work. Controlled Folder Access may block bd without showing a notification, making this hard to diagnose without the -v flag:
Solution: Whitelist bd.exe: Windows Security → Virus & threat protection → Ransomware protection → Controlled folder access → “Allow an app through Controlled folder access” → browse to bd.exe (typically %USERPROFILE%\go\bin\bd.exe). Then retry bd init.

Windows: ENOENT when a Node program spawns bd

Symptom: An editor extension, MCP server, or script that shells out to bd fails on Windows with spawn bd ENOENT, even though bd runs fine in the same terminal. The npm package installs bd as a generated bd.cmd shim, not as an executable named bd. Node’s execFile() and spawn() run their target directly instead of through a shell, so they never apply the PATHEXT resolution that finds bd.cmd — and a batch file is not directly executable in the first place. Solution: Name the shim explicitly and give it a shell:
To avoid a shell — and the argument quoting that comes with it — spawn the native binary the shim wraps, at node_modules/@beads/bd/bin/bd.exe.

Windows: /tmp paths silently land in the drive root

Symptom: A bd command given a /tmp/... path reports success, but the file is not where you look for it — it was written to C:\tmp\.... bd.exe is a native Windows binary and does not share Git Bash’s emulated POSIX filesystem. When a literal /tmp/... string reaches bd, it resolves against the current drive root. In a default interactive Git Bash this usually does not happen — Git for Windows converts standalone POSIX-path arguments to Windows paths before bd.exe sees them. The trap appears when that conversion is out of play:
  • MSYS_NO_PATHCONV=1 or MSYS2_ARG_CONV_EXCL is set (common in Docker-heavy environments)
  • the path comes from a config value or a file, not a command-line argument
  • bd is spawned by a non-MSYS parent — a Node script, editor extension, or MCP server — which passes the string through verbatim:
Solution: Hand bd a Windows path — os.tmpdir() from Node, "$(cygpath -w /tmp)\issues.jsonl" from Git Bash scripts. This applies to any path argument, including --db and config values.

macOS: Gatekeeper blocking execution

  1. Verify the downloaded binary checksum matches the release checksums.txt.
  2. If you used scripts/install.sh, note that macOS ad-hoc re-signing is opt-in (BEADS_INSTALL_RESIGN_MACOS=1).
  3. Approve the binary:

Debug Environment Variables

bd supports environment variables for debugging specific subsystems. Enable them when troubleshooting or when requested by maintainers. Set any of them to 1 to enable; unset to disable.
For multi-repo routing configuration, see Routing.

Getting Help

Debug output

Logs

System info

File an issue

Report at: https://github.com/gastownhall/beads/issues — or ask in GitHub Discussions.