pranshuparmar/witr · warning
process %d not found
Error message
process %d not found
What it means
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.
Source
Thrown at internal/proc/process_darwin.go:35
func ReadProcess(pid int) (model.Process, error) {
if pid <= 0 {
return model.Process{}, fmt.Errorf("invalid pid %d", pid)
}
pidStr := strconv.Itoa(pid)
// Format: pid(0) ppid(1) uid(2) lstart(3-7) state(8) pcpu(9) rss(10) args(11+)
// ucomm is excluded because it can contain spaces (e.g. "Microsoft Teams"),
// which breaks strings.Fields parsing. The display name is derived from args instead.
cmd := exec.Command("ps", "-p", pidStr, "-o", "pid=,ppid=,uid=,lstart=,state=,pcpu=,rss=,args=")
cmd.Env = buildEnvForPS()
out, err := cmd.Output()
if err != nil {
return model.Process{}, fmt.Errorf("process %d not found: %w", pid, err)
}
line := strings.TrimSpace(string(out))
if line == "" {
return model.Process{}, fmt.Errorf("process %d not found", pid)
}
fields := strings.Fields(line)
if len(fields) < 11 {
return model.Process{}, fmt.Errorf("unexpected ps output format for pid %d", pid)
}
ppid, _ := strconv.Atoi(fields[1])
uid, _ := strconv.Atoi(fields[2])
lstartStr := strings.Join(fields[3:8], " ")
startedAt, _ := time.Parse("Mon Jan 2 15:04:05 2006", lstartStr)
if startedAt.IsZero() {
startedAt = time.Now().UTC()
}
state := fields[8]
View on GitHub (pinned to dc4fa1da82)
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).
Defensive patterns
Strategy: validation
Validate before calling
out, err := exec.Command("ps", "-p", strconv.Itoa(pid)).Output()
if err != nil || len(strings.TrimSpace(string(out))) == 0 {
// process not visible/exited — skip ReadProcess
} Try / catch
proc, err := proc.ReadProcess(pid)
if err != nil {
if strings.Contains(err.Error(), "process "+pidStr+" not found") {
// empty ps output: treat identically to the wrapped-error not-found case
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Racing short-lived processes; ps wrappers/aliases in the environment altering behavior; PID reuse checks where the process vanished mid-call.
Related errors
- process %d not found: %w
- process %d not found: %w
- process %d not found
- listfds returned partial record
- launchctl blame failed: %w
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/51bca7739af40bd8.
Report an issue: GitHub.