{"record":{"id":"d43de824205bc28b","repo":"gastownhall/beads","slug":"w-the-dolt-database-is-locked-s-try-bd-doctor","errorCode":null,"errorMessage":"%w\n\nThe Dolt database is locked.%s\nTry: bd doctor --fix (clears stale locks), or kill the holding process.","messagePattern":"%w\n\nThe Dolt database is locked\\.(.+?)\nTry: bd doctor --fix \\(clears stale locks\\), or kill the holding process\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/store.go","lineNumber":702,"sourceCode":"func isLockError(err error) bool {\n\tif err == nil {\n\t\treturn false\n\t}\n\terrStr := strings.ToLower(err.Error())\n\treturn strings.Contains(errStr, \"database is locked\") ||\n\t\tstrings.Contains(errStr, \"lock file\") ||\n\t\tstrings.Contains(errStr, \"noms lock\") ||\n\t\tstrings.Contains(errStr, \"locked by another dolt process\")\n}\n\n// wrapLockError wraps lock-related errors with actionable guidance.\n// Non-lock errors and nil are returned unchanged.\nfunc wrapLockError(err error) error {\n\tif !isLockError(err) {\n\t\treturn err\n\t}\n\thint := lockProcessHint()\n\treturn fmt.Errorf(\"%w\\n\\nThe Dolt database is locked.%s\\n\"+\n\t\t\"Try: bd doctor --fix (clears stale locks), or kill the holding process.\", err, hint)\n}\n\n// lockProcessHint tries to identify the process holding the database lock.\n// Returns a hint string like \" Process 12345 (bd) may be holding the lock.\"\n// Returns empty string if identification fails or on unsupported platforms.\nfunc lockProcessHint() string {\n\t// Look for other bd/dolt processes that might hold the lock\n\tentries, err := os.ReadDir(\"/proc\")\n\tif err != nil {\n\t\t// /proc not available (macOS, Windows, FreeBSD) — skip PID detection\n\t\treturn \"\"\n\t}\n\n\tmyPID := os.Getpid()\n\tvar holders []string\n\tfor _, entry := range entries {\n\t\tif !entry.IsDir() {","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/store.go#L684-L720","documentation":"wrapLockError detects that a database error was caused by the Dolt database being locked and augments it with an actionable message: the original error, an optional hint identifying the holding process, and the recommended remediation (bd doctor --fix to clear stale locks, or kill the holder).","triggerScenarios":"Any SQL operation while another process (or a crashed prior process' leftover lock file) holds the Dolt database lock — concurrent bd commands, an editor session, or a stale .lock file after a crash.","commonSituations":"Running two bd commands simultaneously on the same repo; a previous bd process was SIGKILLed leaving stale locks; a background sync/daemon holds the lock during your command.","solutions":["Run bd doctor --fix to clear stale Dolt locks.","Identify and terminate the holding process (see the 'Process NNNN' hint appended to the error).","Avoid running multiple bd processes against the same database concurrently; retry after the other finishes."],"exampleFix":"// before\n$ bd update bd-1 --status closed\n# fails: database is locked\n// after\n$ bd doctor --fix\n$ bd update bd-1 --status closed","handlingStrategy":"retry","validationCode":"// check for a stale Dolt lock before writing\nif _, err := os.Stat(filepath.Join(repoPath, \".dolt\", \"locks\")); err == nil {\n\t// entries present: another process may hold the lock\n}","typeGuard":"func isLockError(err error) bool {\n\treturn err != nil && strings.Contains(strings.ToLower(err.Error()), \"lock\")\n}","tryCatchPattern":"if err := store.SlotClear(ctx, id, key, actor); err != nil {\n\tif isLockError(err) {\n\t\t// hint: run bd doctor --fix, or kill the holding process, then retry\n\t}\n\treturn err\n}","preventionTips":["Serialize bd commands against the same repo; avoid parallel bd processes.","Terminate bd processes gracefully so lock files are released.","After a crash, run bd doctor --fix before the next write.","Watch for the 'Process NNNN' hint in the message to find the holder."],"tags":["database","locking","dolt","concurrency"],"backgroundTag":"database-locked","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}