pranshuparmar/witr · error
invalid pid %d
Error message
invalid pid %d
What it means
On FreeBSD, ReadProcess validates the PID before invoking ps: pid <= 0 is rejected because `ps -p 0` on FreeBSD returns the kernel swapper, which is not a real userland target, matching the guard on other platforms. It is input validation, not a runtime failure.
Source
Thrown at internal/proc/process_freebsd.go:21
package proc
import (
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"github.com/pranshuparmar/witr/pkg/model"
)
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 == "" {View on GitHub (pinned to dc4fa1da82)
Solutions
- Fix the caller that produced 0/negative PID.
- Skip the call when pid <= 0 and treat it as 'unknown process'.
- Validate PID > 0 before calling witr APIs.
Example fix
// before
proc, err := proc.ReadProcess(pid) // pid == 0
// after
if pid > 0 {
proc, err = proc.ReadProcess(pid)
} Defensive patterns
Strategy: validation
Validate before calling
if pid <= 0 {
return fmt.Errorf("cannot read process: pid %d is invalid", pid)
} Try / catch
proc, err := proc.ReadProcess(pid)
if err != nil {
if strings.Contains(err.Error(), "invalid pid") {
// input bug: do not retry; fix the PID source
}
} Prevention
- Validate PID > 0 at the boundary of your own API
- Use nil/flags instead of 0 to represent 'no process'
- Guard against zero-valued structs leaking into lookups
When it happens
Trigger: Calling ReadProcess (directly or via pidIdentityChanged) with pid <= 0 — typically an uninitialized/zero PID or a sentinel meaning 'no parent found'.
Common situations: Passing 0 for a not-yet-discovered parent PID; zero-valued struct fields flowing into the lookup.
Related errors
- invalid pid %d
- process %d not found: %w
- process %d not found
- unexpected ps output format for pid %d: got %d fields in %q
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/ad0b5ca94e327727.
Report an issue: GitHub.