{"record":{"id":"1fca13118162aff4","repo":"gastownhall/beads","slug":"failed-to-create-lock-file-w","errorCode":null,"errorMessage":"failed to create lock file: %w","messagePattern":"failed to create lock file: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dolt/bootstrap.go","lineNumber":230,"sourceCode":"// Uses non-blocking flock with polling to respect the timeout deadline.\n// Detects and cleans up stale lock files from crashed processes.\nfunc acquireBootstrapLock(lockPath string, timeout time.Duration) (*os.File, error) {\n\t// Check for stale lock file before attempting to acquire.\n\t// If the lock file is very old, the holding process likely crashed\n\t// without cleanup. Remove it so we can proceed.\n\tif info, err := os.Stat(lockPath); err == nil {\n\t\tage := time.Since(info.ModTime())\n\t\tif age > staleLockAge {\n\t\t\tfmt.Fprintf(os.Stderr, \"Bootstrap: removing stale lock file (age: %s)\\n\", age.Round(time.Second))\n\t\t\t_ = os.Remove(lockPath) // Best effort cleanup of lock file\n\t\t}\n\t}\n\n\t// Create lock file\n\t// #nosec G304 - controlled path\n\tf, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0600)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create lock file: %w\", err)\n\t}\n\n\t// Try to acquire lock with non-blocking flock and polling.\n\tdeadline := time.Now().Add(timeout)\n\tfor {\n\t\terr := lockfile.FlockExclusiveNonBlocking(f)\n\t\tif err == nil {\n\t\t\t// Lock acquired - update modification time for stale detection\n\t\t\treturn f, nil\n\t\t}\n\n\t\tif !lockfile.IsLocked(err) {\n\t\t\t// Unexpected error (not contention)\n\t\t\t_ = f.Close() // Best effort cleanup on error path\n\t\t\treturn nil, fmt.Errorf(\"failed to acquire bootstrap lock: %w\", err)\n\t\t}\n\n\t\tif time.Now().After(deadline) {","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dolt/bootstrap.go#L212-L248","documentation":"acquireBootstrapLock creates a bootstrap lock file (mode 0600) with os.OpenFile before trying to flock it. This error means the lock file itself could not be created/opened — the process never even got to the locking stage. It wraps the underlying OS error.","triggerScenarios":"os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0600) fails: the `.beads` directory does not exist, the filesystem is read-only, permission denied on the lock path, disk full, or the path is invalid (e.g. wrong working directory).","commonSituations":"Running `bd bootstrap` in a directory where `.beads` has not been created or is not writable; running under a user without write permission to the repo; a read-only container/mount or full disk.","solutions":["Check that the lock file's parent directory exists and is writable (e.g. `ls -la .beads/` and `touch .beads/test` as the same user)","Fix permissions: `chmod u+w .beads` or run as a user with write access to the repository","Check for read-only filesystem or full disk (`mount`, `df -h`) and free space or remount read-write"],"exampleFix":"// before\nbd bootstrap\n// error: failed to create lock file: open .beads/bootstrap.lock: permission denied\n// after\nmkdir -p .beads && chmod u+w .beads\nbd bootstrap","handlingStrategy":"validation","validationCode":"// ensure lock dir exists and is writable before bootstrap\ninfo, err := os.Stat(beadsDir)\nif err != nil || !info.IsDir() { os.MkdirAll(beadsDir, 0o755) }\nif f, err := os.CreateTemp(beadsDir, \".writetest\"); err != nil {\n    // directory not writable: fix permissions before bootstrap\n} else { f.Close(); os.Remove(f.Name()) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run bd from the repository root so relative .beads paths resolve","Verify the user has write permission on .beads/ before automating bootstrap","Check disk space and that the volume is mounted read-write","Create .beads/ (via bd init) before calling bootstrap"],"tags":["filesystem","permissions","lock-file","bootstrap"],"backgroundTag":"lock-file-create-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}