pranshuparmar/witr · error
unexpected ps output format for pid %d: got %d fields in %q
Error message
unexpected ps output format for pid %d: got %d fields in %q
What it means
FreeBSD ReadProcess expects a fixed ps column layout (pid ppid uid jid state pcpu rss lstart(5 fields) args...) requiring at least 12 fields. When fewer fields arrive, parsing aborts with this error, which helpfully includes the actual field count and the raw line to diagnose format drift.
Source
Thrown at internal/proc/process_freebsd.go:45
// 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()
}
rawCmdline := ""
if len(fields) > 12 {
rawCmdline = strings.Join(fields[12:], " ")View on GitHub (pinned to dc4fa1da82)
Solutions
- Run `ps -p <pid> -o pid= -o ppid= -o uid= -o jid= -o state= -o pcpu= -o rss= -o lstart= -o args=` manually and compare against the expected 12+ field layout.
- Ensure the system ps (/bin/ps) is used — remove wrappers/shims from PATH.
- Run with a standard locale (LC_ALL=C) to rule out localization effects.
- Use the got-N-fields and raw line in the message to identify which column is missing and report/patch accordingly.
Example fix
# before (diagnose) ps -p 1234 -o pid= -o ppid= -o uid= -o jid= -o state= -o pcpu= -o rss= -o lstart= -o args= # after (force standard env) LC_ALL=C /bin/ps -p 1234 -o pid= -o ppid= -o uid= -o jid= -o state= -o pcpu= -o rss= -o lstart= -o args=
Defensive patterns
Strategy: validation
Validate before calling
// FreeBSD: verify expected 12+ field layout once at startup
out, _ := exec.Command("ps", "-p", "1", "-o", "pid=", "-o", "ppid=", "-o", "uid=", "-o", "jid=", "-o", "state=", "-o", "pcpu=", "-o", "rss=", "-o", "lstart=", "-o", "args=").Output()
if out != nil && len(strings.Fields(strings.TrimSpace(string(out)))) < 12 {
// non-standard ps output detected
} Try / catch
proc, err := proc.ReadProcess(pid)
if err != nil {
if strings.Contains(err.Error(), "unexpected ps output format") {
// log err fully: it includes field count and raw line for diagnosis
}
} Prevention
- Keep LC_ALL=C when spawning ps for parsing
- Ensure /bin/ps is the real system ps (no shims in PATH)
- Use the error's embedded raw line to detect format drift early
- Pin/test the ps column layout on all target FreeBSD versions
When it happens
Trigger: ReadProcess receiving ps output with < 12 whitespace-separated fields — a non-standard ps (BusyBox/toybox), a shimmed or wrapper ps in PATH, or a ps that truncates/ignores the -o spec.
Common situations: Minimal FreeBSD environments with alternate ps implementations; ps aliased/wrapped in shell profiles; output corruption or locale changes altering the lstart columns.
Related errors
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/498091b0a8f15023.
Report an issue: GitHub.