{"record":{"id":"862b2e4b5edc0890","repo":"gastownhall/beads","slug":"read-command-line-for-pid-d-w","errorCode":null,"errorMessage":"read command line for pid %d: %w","messagePattern":"read command line for pid (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/unverified_process_darwin.go","lineNumber":44,"sourceCode":"\tif killErr := syscall.Kill(pid, 0); errors.Is(killErr, unix.ESRCH) {\n\t\treturn nil, true, nil\n\t}\n\treturn &unverifiedProcess{pid: pid}, false, nil\n}\n\nfunc (p *unverifiedProcess) executableBasename() (basename string, gone bool, err error) {\n\treturn processExecutableBasename(p.pid)\n}\n\n// commandLineContains reports whether the process command line contains\n// 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 {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/unverified_process_darwin.go#L26-L62","documentation":"On macOS, unverifiedProcess.commandLineContains inspects a PID's arguments by running `ps -p <pid> -o args=`. If ps fails and a follow-up kill(pid,0) shows the process still exists (not ESRCH), the ps failure is wrapped in this error. This keeps the force-stop path safe: the proxy cannot verify what the PID is running, so it refuses to act rather than guessing.","triggerScenarios":"commandLineContains runs exec.Command(\"ps\", \"-p\", pid, \"-o\", \"args=\") and it errors while syscall.Kill(pid, 0) does NOT return ESRCH — i.e. ps failed but the process appears alive.","commonSituations":"Sandboxed/restricted macOS environments where spawning ps fails; ps binary missing from PATH; transient resource exhaustion preventing fork/exec; zombie or system-protected processes ps cannot report on.","solutions":["Verify /bin/ps works standalone: `ps -p <pid> -o args=` — fix PATH or environment if it fails there.","Re-run the command; transient fork/exec failures often clear on retry.","Check whether the process is a zombie (state Z in `ps aux | grep <pid>`); reap the parent or wait for it to exit.","Manually kill the PID after verifying its identity, then remove the stale pidfile."],"exampleFix":"// before: PATH stripped in daemon env, ps not found\nPATH=/usr/bin:/bin:/usr/sbin:/sbin bd ...\n// after: ensure standard paths so exec ps succeeds\nexport PATH=\"/usr/bin:/bin:/usr/sbin:/sbin:$PATH\"","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"matched, gone, err := proc.commandLineContains(needle)\nif err != nil {\n    if _, statErr := exec.LookPath(\"ps\"); statErr != nil {\n        // environment problem: fix PATH or inspect the PID manually\n    }\n    return fmt.Errorf(\"cannot verify pid identity, refusing to kill: %w\", err)\n}","preventionTips":["Keep /bin/ps available and standard PATH entries intact in daemon/service environments.","Avoid running bd inside heavily sandboxed exec wrappers that block spawning child processes.","If ps repeatedly fails, verify PIDs manually with `ps -p <pid> -o args=` before any cleanup."],"tags":["go","darwin","process-inspection","ps","exec"],"backgroundTag":"process-inspection-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}