{"record":{"id":"cedfd0524db922b5","repo":"gastownhall/beads","slug":"proxy-forcestopunverified-re-read-s-w","errorCode":null,"errorMessage":"proxy.ForceStopUnverified: re-read %s: %w","messagePattern":"proxy\\.ForceStopUnverified: re-read (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/force_stop.go","lineNumber":311,"sourceCode":"\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}\n\tif current == nil {\n\t\treturn nil\n\t}\n\tif *current != *record {\n\t\treturn fmt.Errorf(\n\t\t\t\"proxy.ForceStopUnverified: record %s changed after pid %d was stopped; refusing to quarantine the replacement\",\n\t\t\treport.RecordPath,\n\t\t\trecord.Pid,\n\t\t)\n\t}\n\ttarget, err := quarantineRecord(rootDir, pidName, time.Now())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"proxy.ForceStopUnverified: quarantine %s: %w\", report.RecordPath, err)\n\t}\n\treport.QuarantinedPath = target\n\treturn nil\n}","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/force_stop.go#L293-L329","documentation":"This error is returned by quarantineForceStopRecord when it re-reads the pidfile record just before quarantining it and the read itself fails. At this point the recorded process has already been stopped (or was already gone), but force-stop cannot confirm the record is unchanged, so it refuses to quarantine. The wrapped cause (%w) carries the underlying read error.","triggerScenarios":"Call ForceStopUnverified (`bd dolt stop --force`) after the PID has been successfully inspected/signaled; quarantineForceStopRecord's pidfile.Read(rootDir, pidName) returns an error instead of nil (record gone) or a valid record — e.g. the record file became unreadable, was partially deleted, or a filesystem error occurred.","commonSituations":"Another bd/dolt process deleted or replaced the record between the first read and the re-read; filesystem permission changes mid-operation; disk errors or read-only remount; concurrent `bd dolt stop --force` runs racing to clean the same record.","solutions":["Re-run `bd dolt stop --force`; if the record was deleted by a concurrent operation, the next run takes the RecordFound=false path and succeeds","Fix the underlying read error from the wrapped cause (permissions, filesystem state) on <rootDir>/proxy.pid or proxy-child.pid","Check whether another bd/dolt process or backup tool is concurrently manipulating the pidfile and serialize your operations","If the process is confirmed stopped, remove or rename the record manually (proxy.pid to proxy.pid.stale-<unix-timestamp>) to complete recovery"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm the pidfile is readable and stable before force-stop:\ndata, err := os.ReadFile(filepath.Join(rootDir, \"proxy.pid\"))\nif err != nil { /* fix permissions/filesystem first */ }","typeGuard":null,"tryCatchPattern":"report, err := proxy.ForceStopUnverified(rootDir)\nif err != nil && strings.Contains(err.Error(), \"re-read\") {\n    // Process was stopped but quarantine failed; retry once — if the record is\n    // now gone the run succeeds via the RecordFound=false path\n    report, err = proxy.ForceStopUnverified(rootDir)\n}","preventionTips":["Do not delete or edit proxy.pid / proxy-child.pid manually while bd is running","Exclude the workspace from concurrent backup/sync tools that touch pidfiles during bd operations","Ensure stable filesystem permissions on the workspace root for the duration of the command","If this error recurs, quarantine manually: rename the pidfile to <name>.stale-<unix-timestamp> after confirming the PID is dead"],"tags":["pidfile","go","filesystem","force-stop"],"backgroundTag":"pidfile-read-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}