{"record":{"id":"909146ca428308d5","repo":"gastownhall/beads","slug":"proxy-forcestopunverified-refusing-to-signal-pid","errorCode":null,"errorMessage":"proxy.ForceStopUnverified: refusing to signal pid %d from %s: executable basename is %q, want bd or dolt","messagePattern":"proxy\\.ForceStopUnverified: refusing to signal pid (.+?) from (.+?): executable basename is %q, want bd or dolt","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/storage/dbproxy/proxy/force_stop.go","lineNumber":217,"sourceCode":"\t}\n\tif gone {\n\t\treport.ProcessWasGone = true\n\t\treturn nil\n\t}\n\tdefer proc.close()\n\n\texecutable, gone, err := proc.executableBasename()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"proxy.ForceStopUnverified: inspect executable for pid %d: %w\", pid, err)\n\t}\n\tif gone {\n\t\treport.ProcessWasGone = true\n\t\treturn nil\n\t}\n\texecutable = normalizeForceStopExecutable(executable)\n\treport.Executable = executable\n\tif executable != \"bd\" && executable != \"dolt\" {\n\t\treturn fmt.Errorf(\n\t\t\t\"proxy.ForceStopUnverified: refusing to signal pid %d from %s: executable basename is %q, want bd or dolt\",\n\t\t\tpid,\n\t\t\treport.RecordPath,\n\t\t\texecutable,\n\t\t)\n\t}\n\n\t// Basename alone would let a recycled PID now running an unrelated bd or\n\t// dolt be killed; require the command line to tie the process to THIS\n\t// workspace, and refuse when that scope cannot be established.\n\tscoped, gone, err := proc.commandLineContains(rootDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\n\t\t\t\"proxy.ForceStopUnverified: refusing to signal pid %d from %s: workspace scope could not be established (%v); stop the process manually, then quarantine the record by renaming %s to %s.stale-<unix-timestamp> before retrying\",\n\t\t\tpid,\n\t\t\treport.RecordPath,\n\t\t\terr,\n\t\t\treport.RecordPath,","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/force_stop.go#L199-L235","documentation":"ForceStopUnverified only signals processes whose executable basename is exactly bd or dolt after normalization. The PID from the unverified record resolved to a different binary, so bd refuses to send a signal — the PID was recycled or the record was forged/stale and now points at an unrelated process. This is a deliberate kill-safety guard to prevent killing innocent processes.","triggerScenarios":"Calling proxy.ForceStopUnverified with a PID record whose PID has been recycled by the OS and reassigned to a non-bd/non-dolt process (e.g. sshd, python), or a record that was hand-edited/copied and never pointed at bd or dolt.","commonSituations":"Long-lived machines where PIDs wrap around and stale .pid files in a workspace refer to reused PIDs; containers restarted with different PID assignments; users copying pid files between workspaces; upgrading such that a different daemon now owns the port.","solutions":["Verify with ps -p <pid> -o comm= what the process actually is; if it is not yours, do not kill it","Quarantine the stale record: rename <record> to <record>.stale-<unix-timestamp>, then retry force-stop","If the process is yours and unrelated to bd, stop it manually yourself","Regenerate the workspace state so a fresh, correct PID record is written"],"exampleFix":"// before (manually deleting or ignoring the refusal)\n// rm .bd/bd.pid && bd doctor --fix\n// after: quarantine instead of delete so history is auditable\nmv .bd/bd.pid .bd/bd.pid.stale-$(date +%s)\nbd doctor --fix","handlingStrategy":"validation","validationCode":"// before force-stop, confirm the recorded pid still runs bd/dolt\npid := readPidFromRecord(recordPath)\ncomm, _ := os.ReadFile(fmt.Sprintf(\"/proc/%d/comm\", pid))\nname := strings.TrimSpace(string(comm))\nif name != \"bd\" && name != \"dolt\" {\n    os.Rename(recordPath, recordPath+\".stale-\"+fmt.Sprint(time.Now().Unix())) // recycled pid\n}","typeGuard":"func isExecutableMismatchErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"executable basename is\")\n}","tryCatchPattern":null,"preventionTips":["Clean up stale pid records promptly instead of leaving them for PID reuse windows","Avoid copying pid files between workspaces or machines","Prefer graceful proxy.Shutdown on v2 records; reserve ForceStopUnverified for genuinely unverifiable legacy records","Monitor PID wraparound on long-running hosts (small pid_max increases reuse PIDs faster)"],"tags":["pid-recycling","safety-guard","pidfile","force-stop"],"backgroundTag":"pid-recycled-by-unrelated-process","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}