{"record":{"id":"dfbbadd5a73be535","repo":"gastownhall/beads","slug":"signal-pid-d-w","errorCode":null,"errorMessage":"signal pid %d: %w","messagePattern":"signal pid (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/unverified_process_darwin.go","lineNumber":55,"sourceCode":"// needle, read best-effort through ps.\nfunc (p *unverifiedProcess) commandLineContains(needle string) (matched bool, gone bool, err error) {\n\toutput, commandErr := exec.Command(\"ps\", \"-p\", strconv.Itoa(p.pid), \"-o\", \"args=\").Output()\n\tif commandErr != nil {\n\t\tif killErr := syscall.Kill(p.pid, 0); errors.Is(killErr, unix.ESRCH) {\n\t\t\treturn false, true, nil\n\t\t}\n\t\treturn false, false, fmt.Errorf(\"read command line for pid %d: %w\", p.pid, commandErr)\n\t}\n\treturn strings.Contains(strings.TrimSpace(string(output)), needle), false, nil\n}\n\n// kill sends SIGKILL. gone reports a target that had already exited.\nfunc (p *unverifiedProcess) kill() (gone bool, err error) {\n\tif killErr := syscall.Kill(p.pid, syscall.SIGKILL); killErr != nil {\n\t\tif errors.Is(killErr, unix.ESRCH) {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"signal pid %d: %w\", p.pid, killErr)\n\t}\n\treturn false, nil\n}\n\nfunc (p *unverifiedProcess) exited() (bool, error) {\n\t_, gone, err := processExecutableBasename(p.pid)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn gone, nil\n}\n\nfunc (p *unverifiedProcess) close() {}\n","sourceCodeStart":37,"sourceCodeEnd":69,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/unverified_process_darwin.go#L37-L69","documentation":"unverifiedProcess.kill on macOS sends SIGKILL to the recorded PID. ESRCH (process already gone) is treated as success; any other signal error is wrapped in this error. The library refuses to silently continue when it cannot confirm the target was killed, since the PID's identity was never fully verified.","triggerScenarios":"kill() calls syscall.Kill(pid, SIGKILL) and receives an error other than ESRCH — e.g. EPERM (owned by another user), or the PID was recycled into a protected system process.","commonSituations":"The stale daemon PID now belongs to a root-owned or another-user process (PID recycling); running without sufficient privileges in a container; macOS seatbelt/sandbox blocking signals.","solutions":["Re-run with sufficient privileges (sudo) if EPERM is the underlying cause, after manually confirming the PID's identity with `ps -p <pid> -o args=`.","Verify with `ps -p <pid>` whether the PID was recycled to an unrelated process; if so, do NOT kill it — remove the stale pidfile instead.","Check sandbox/container policies that block signals and adjust them.","Restart the terminal session/daemon cleanly so a fresh pidfile with a live PID is written."],"exampleFix":"// before: EPERM killing other-user process\nsudo kill -9 <pid>   # only after verifying identity\n// after: stale record cleaned\nrm .beads/bd.pid && bd ...","handlingStrategy":"try-catch","validationCode":"out, err := exec.Command(\"ps\", \"-o\", \"user=\", \"-p\", strconv.Itoa(pid)).Output()\nif err == nil && strings.TrimSpace(string(out)) != currentUser {\n    // PID likely recycled to another user: do not signal\n}","typeGuard":null,"tryCatchPattern":"gone, err := proc.kill()\nif err != nil {\n    var errno syscall.Errno\n    if errors.As(err, &errno) && errno == syscall.EPERM {\n        // verify identity manually; never blind-sudo a recycled PID\n    }\n    return err\n}","preventionTips":["Run the stop command as the same user that started the daemon.","Verify a PID's identity (ps -p <pid> -o args=,user=) before elevating privileges to kill it.","Clean up stale pidfiles after abnormal daemon exits so old PIDs are not reused.","Be extra careful on long-lived systems where PID wraparound/recycling is likely."],"tags":["go","darwin","signal","sigkill","process-management"],"backgroundTag":"process-kill-signal-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}