pranshuparmar/witr · warning
process %d not found: %w
Error message
process %d not found: %w
What it means
FreeBSD ReadProcess runs `ps -p <pid> -o ...`; a non-zero ps exit (normally because the PID does not exist) yields this error with the exec error wrapped via %w. It is the primary 'process is gone' signal on FreeBSD.
Source
Thrown at internal/proc/process_freebsd.go:35
func ReadProcess(pid int) (model.Process, error) {
// Reject PID 0 (and negatives): on FreeBSD `ps -p 0` returns the kernel
// swapper, which is not a real userland target. Matches the other platforms.
if pid <= 0 {
return model.Process{}, fmt.Errorf("invalid pid %d", pid)
}
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)View on GitHub (pinned to dc4fa1da82)
Solutions
- Verify the PID exists (`ps -p <pid>`) before retrying; if not, the process is gone.
- Retry promptly to minimize the exit race.
- Inspect the wrapped error to distinguish 'No such process' from 'executable not found' (install/procps availability issue).
- Inspect the parent process instead if the child exited; check for PID reuse with fresh data.
Defensive patterns
Strategy: try-catch
Validate before calling
// FreeBSD: existence check before ReadProcess
if out, err := exec.Command("ps", "-p", strconv.Itoa(pid), "-o", "pid=").Output(); err != nil || len(strings.TrimSpace(string(out))) == 0 {
return fmt.Errorf("pid %d not running", pid)
} Try / catch
proc, err := proc.ReadProcess(pid)
if err != nil {
if strings.Contains(err.Error(), "not found") {
// target exited: unwrap %w to confirm 'No such process'
}
} Prevention
- Read the process promptly after PID discovery
- Confirm ps exists in jails/containers where the tool runs
- Unwrap the error to separate process-exit from environment failures
When it happens
Trigger: ReadProcess on a PID that already terminated (ps exit 1), or exec failures such as ps missing from PATH, both surfaced wrapped in this message.
Common situations: Target exited between discovery and lookup; minimal jails/containers lacking ps; supervisor restarted the process with a new PID.
Related errors
- process %d not found
- 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/88fd661d262d87e7.
Report an issue: GitHub.