{"record":{"id":"812e8bedbedd4d9b","repo":"gastownhall/beads","slug":"proxy-forcestopunverified-acquire-s-w","errorCode":null,"errorMessage":"proxy.ForceStopUnverified: acquire %s: %w","messagePattern":"proxy\\.ForceStopUnverified: acquire (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/force_stop.go","lineNumber":294,"sourceCode":"\t\ttime.Sleep(shutdownConfirmPoll)\n\t}\n}\n\nfunc normalizeForceStopExecutable(name string) string {\n\tname = strings.TrimSpace(filepath.Base(name))\n\tname = strings.TrimSuffix(name, \" (deleted)\")\n\tname = strings.TrimSuffix(strings.ToLower(name), \".exe\")\n\treturn name\n}\n\nfunc acquireForceStopLock(lockPath string, deadline time.Time) (*util.Lock, error) {\n\tfor {\n\t\tlock, err := util.TryLock(lockPath)\n\t\tif err == nil {\n\t\t\treturn lock, nil\n\t\t}\n\t\tif !lockfile.IsLocked(err) {\n\t\t\treturn nil, fmt.Errorf(\"proxy.ForceStopUnverified: acquire %s: %w\", lockPath, err)\n\t\t}\n\t\tif time.Now().After(deadline) {\n\t\t\treturn nil, fmt.Errorf(\"proxy.ForceStopUnverified: timeout acquiring %s after signaling\", lockPath)\n\t\t}\n\t\ttime.Sleep(shutdownConfirmPoll)\n\t}\n}\n\nfunc quarantineForceStopRecord(\n\trootDir string,\n\tpidName string,\n\trecord *pidfile.PidFile,\n\treport *ForceStopReport,\n) error {\n\tcurrent, err := pidfile.Read(rootDir, pidName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"proxy.ForceStopUnverified: re-read %s: %w\", report.RecordPath, err)\n\t}","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/force_stop.go#L276-L312","documentation":"This error is returned by acquireForceStopLock when, after inspecting and signaling the unverified PID, re-attempting to take the workspace lock file fails with an error that is NOT 'lock is held' (lockfile.IsLocked(err) is false). That means TryLock itself failed — e.g. filesystem error creating/opening the lock file, permission problem, or path issue — rather than mere contention. The wrapped cause (%w) carries the underlying reason.","triggerScenarios":"Call ForceStopUnverified (`bd dolt stop --force`) on a record whose lock was held by another process (LockWasHeld=true path); after signaling the PID, the retry loop's util.TryLock(lockPath) returns a non-IsLocked error — e.g. read-only filesystem, deleted parent directory, or permission denied on the lock path.","commonSituations":"Workspace directory made read-only or moved while force-stop runs; another tool deleted/recreated the lock path mid-operation; running under a user without write permission to the workspace root; disk-full conditions preventing lock file creation.","solutions":["Inspect the wrapped cause to identify the filesystem failure (permission denied, ENOENT, EROFS, ENOSPC) and fix the workspace directory state","Restore write permissions on the workspace root: chmod u+w <rootDir> (and its parent) so the lock file can be created","If the workspace was moved/renamed, re-run force-stop from the correct workspace path so lockPath resolves","Confirm the process was actually stopped (ps -p <pid>), then quarantine the record manually (rename proxy.pid to proxy.pid.stale-<unix-timestamp>) to recover without the lock"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the workspace is writable and the lock path is creatable before force-stop:\nlockPath := filepath.Join(rootDir, \"proxy.lock\")\nif err := os.Chmod(rootDir, 0o755); err != nil { return err }\nprobe, err := os.OpenFile(lockPath, os.O_CREATE|os.O_WRONLY, 0o644)\nif err != nil { return err }\nprobe.Close()","typeGuard":null,"tryCatchPattern":"report, err := proxy.ForceStopUnverified(rootDir)\nif err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) {\n        // Non-contention lock failure: fix filesystem/permissions at pathErr.Path, then retry\n    }\n}","preventionTips":["Run bd as a user with write access to the workspace root","Do not move, rename, or make read-only a workspace while bd commands may run","Keep the workspace on a local filesystem with working flock semantics (not NFS without proper lock support)","Watch disk space; ENOSPC surfaces as this acquisition error rather than lock contention"],"tags":["file-lock","go","filesystem","force-stop"],"backgroundTag":"lock-acquisition-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}