{"record":{"id":"c19480416012ee5f","repo":"pranshuparmar/witr","slug":"process-d-not-found-c19480","errorCode":null,"errorMessage":"process %d not found","messagePattern":"process (.+?) not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/proc/process_freebsd.go","lineNumber":40,"sourceCode":"\t}\n\tpidStr := strconv.Itoa(pid)\n\n\t// Format: pid(0) ppid(1) uid(2) jid(3) state(4) pcpu(5) rss(6) lstart(7-11) args(12+)\n\t// comm is excluded because it can contain spaces, which breaks strings.Fields parsing.\n\t// The display name is derived from args instead.\n\tcmd := exec.Command(\"ps\", \"-p\", pidStr,\n\t\t\"-o\", \"pid=\", \"-o\", \"ppid=\", \"-o\", \"uid=\", \"-o\", \"jid=\",\n\t\t\"-o\", \"state=\", \"-o\", \"pcpu=\", \"-o\", \"rss=\",\n\t\t\"-o\", \"lstart=\", \"-o\", \"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) < 12 {\n\t\treturn model.Process{}, fmt.Errorf(\"unexpected ps output format for pid %d: got %d fields in %q\", pid, len(fields), line)\n\t}\n\n\tppid, _ := strconv.Atoi(fields[1])\n\tuid, _ := strconv.Atoi(fields[2])\n\tjid := fields[3]\n\tstate := fields[4]\n\tcpuPct, _ := strconv.ParseFloat(fields[5], 64)\n\trssKB, _ := strconv.ParseFloat(fields[6], 64)\n\n\tlstartStr := strings.Join(fields[7:12], \" \")\n\tstartedAt := parseLstart(lstartStr)\n\tif startedAt.IsZero() {\n\t\tstartedAt = time.Now().UTC()","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/pranshuparmar/witr/blob/dc4fa1da82d3e266fcbd928641b4f30b3077c64f/internal/proc/process_freebsd.go#L22-L58","documentation":"After a successful ps run, FreeBSD ReadProcess requires a non-empty output line; an empty line means ps matched nothing — effectively 'process not found' with a zero exit code. It is separated from the wrapped-error path because the underlying exec error is unavailable.","triggerScenarios":"ReadProcess on a PID that ps resolves to zero output rows — the process exited during the ps call, or a visibility edge where ps exits 0 with no match.","commonSituations":"Racing very short-lived processes; ps behavior differences inside jails; stale PID from a cache.","solutions":["Confirm the PID exists with an independent `ps -p <pid>`; treat empty output as process-not-found.","Retry once quickly; persistent emptiness means the process is gone.","Check jail/container visibility if the PID is known to be alive from another vantage point.","Look for PID reuse: re-fetch the PID from the source that reported 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    // no rows: process gone or not visible in this jail\n}","typeGuard":null,"tryCatchPattern":"proc, err := proc.ReadProcess(pid)\nif err != nil {\n    if strings.Contains(err.Error(), \"process \"+pidStr+\" not found\") && !strings.Contains(err.Error(), \": %\") {\n        // empty output path: handle as process-not-found\n    }\n}","preventionTips":["Handle the empty-output and wrapped-error not-found cases the same way","Check jail visibility when the PID is known alive elsewhere","Avoid caching PIDs across supervisor restarts"],"tags":["freebsd","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"}