{"record":{"id":"51bca7739af40bd8","repo":"pranshuparmar/witr","slug":"process-d-not-found","errorCode":null,"errorMessage":"process %d not found","messagePattern":"process (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/proc/process_darwin.go","lineNumber":35,"sourceCode":"func ReadProcess(pid int) (model.Process, error) {\n\tif pid <= 0 {\n\t\treturn model.Process{}, fmt.Errorf(\"invalid pid %d\", pid)\n\t}\n\tpidStr := strconv.Itoa(pid)\n\n\t// Format: pid(0) ppid(1) uid(2) lstart(3-7) state(8) pcpu(9) rss(10) args(11+)\n\t// ucomm is excluded because it can contain spaces (e.g. \"Microsoft Teams\"),\n\t// which breaks strings.Fields parsing. The display name is derived from args instead.\n\tcmd := exec.Command(\"ps\", \"-p\", pidStr, \"-o\", \"pid=,ppid=,uid=,lstart=,state=,pcpu=,rss=,args=\")\n\tcmd.Env = buildEnvForPS()\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\treturn model.Process{}, fmt.Errorf(\"process %d not found: %w\", pid, err)\n\t}\n\n\tline := strings.TrimSpace(string(out))\n\tif line == \"\" {\n\t\treturn model.Process{}, fmt.Errorf(\"process %d not found\", pid)\n\t}\n\n\tfields := strings.Fields(line)\n\tif len(fields) < 11 {\n\t\treturn model.Process{}, fmt.Errorf(\"unexpected ps output format for pid %d\", pid)\n\t}\n\n\tppid, _ := strconv.Atoi(fields[1])\n\tuid, _ := strconv.Atoi(fields[2])\n\n\tlstartStr := strings.Join(fields[3:8], \" \")\n\tstartedAt, _ := time.Parse(\"Mon Jan 2 15:04:05 2006\", lstartStr)\n\tif startedAt.IsZero() {\n\t\tstartedAt = time.Now().UTC()\n\t}\n\n\tstate := fields[8]\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/pranshuparmar/witr/blob/dc4fa1da82d3e266fcbd928641b4f30b3077c64f/internal/proc/process_darwin.go#L17-L53","documentation":"After ps succeeds, ReadProcess expects a non-empty line of output; an empty response means ps accepted the -p filter but printed nothing, i.e. the process does not exist (or is not visible to the current user in some configurations). Distinct from error 23 because ps exited successfully.","triggerScenarios":"ReadProcess called on a PID that ps resolves to zero lines — the process exited in the window between ps's internal lookup and output, or a permissions/visibility edge case where ps exits 0 with no rows.","commonSituations":"Racing short-lived processes; ps wrappers/aliases in the environment altering behavior; PID reuse checks where the process vanished mid-call.","solutions":["Confirm the PID exists with a separate `ps -p <pid>` check before calling.","Treat it as 'process not found' and handle like the wrapped-error case (error 23).","Retry once quickly; if it fails again the process is gone.","If reproducible for a live PID, check that the `ps` in PATH is the system ps (buildEnvForPS minimizes env interference; verify no wrapper shadows it)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"ps\", \"-p\", strconv.Itoa(pid)).Output()\nif err != nil || len(strings.TrimSpace(string(out))) == 0 {\n    // process not visible/exited — skip ReadProcess\n}","typeGuard":null,"tryCatchPattern":"proc, err := proc.ReadProcess(pid)\nif err != nil {\n    if strings.Contains(err.Error(), \"process \"+pidStr+\" not found\") {\n        // empty ps output: treat identically to the wrapped-error not-found case\n    }\n}","preventionTips":["Retry once quickly before declaring the process gone","Ensure the system ps is used, not a wrapper/alias","Treat both not-found variants (23 and 24) uniformly in error handling"],"tags":["macos","process-exited","ps"],"backgroundTag":"process-not-found","analyzedSha":"dc4fa1da82d3e266fcbd928641b4f30b3077c64f","analyzedAt":"2026-09-01T12:17:08.767Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}