pranshuparmar/witr · warning
process %d not found
Error message
process %d not found
What it means
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.
Source
Thrown at internal/proc/process_freebsd.go:40
}
pidStr := strconv.Itoa(pid)
// Format: pid(0) ppid(1) uid(2) jid(3) state(4) pcpu(5) rss(6) lstart(7-11) args(12+)
// comm is excluded because it can contain spaces, which breaks strings.Fields parsing.
// The display name is derived from args instead.
cmd := exec.Command("ps", "-p", pidStr,
"-o", "pid=", "-o", "ppid=", "-o", "uid=", "-o", "jid=",
"-o", "state=", "-o", "pcpu=", "-o", "rss=",
"-o", "lstart=", "-o", "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) < 12 {
return model.Process{}, fmt.Errorf("unexpected ps output format for pid %d: got %d fields in %q", pid, len(fields), line)
}
ppid, _ := strconv.Atoi(fields[1])
uid, _ := strconv.Atoi(fields[2])
jid := fields[3]
state := fields[4]
cpuPct, _ := strconv.ParseFloat(fields[5], 64)
rssKB, _ := strconv.ParseFloat(fields[6], 64)
lstartStr := strings.Join(fields[7:12], " ")
startedAt := parseLstart(lstartStr)
if startedAt.IsZero() {
startedAt = time.Now().UTC()View on GitHub (pinned to dc4fa1da82)
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.
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 {
// no rows: process gone or not visible in this jail
} Try / catch
proc, err := proc.ReadProcess(pid)
if err != nil {
if strings.Contains(err.Error(), "process "+pidStr+" not found") && !strings.Contains(err.Error(), ": %") {
// empty output path: handle as process-not-found
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Racing very short-lived processes; ps behavior differences inside jails; stale PID from a cache.
Related errors
- process %d not found: %w
- process %d not found: %w
- process %d not found
- process %d not found in snapshot
- invalid pid %d
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/c19480416012ee5f.
Report an issue: GitHub.