pranshuparmar/witr · error
invalid pid %d
Error message
invalid pid %d
What it means
On macOS, ReadProcess shells out to `ps` and refuses to run at all for non-positive PIDs. PID 0 is the kernel and negative values are never valid userland PIDs, so there is nothing to read. The error is a pure input-validation guard.
Source
Thrown at internal/proc/process_darwin.go:19
//go:build darwin
package proc
import (
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"sync"
"time"
"github.com/pranshuparmar/witr/pkg/model"
)
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)
}
View on GitHub (pinned to dc4fa1da82)
Solutions
- Check the pid value at the call site; fix the source that produced 0/negative.
- Treat pid 0 as 'unknown process' in your logic and skip the ReadProcess call.
- Validate PID > 0 before invoking witr APIs.
Example fix
// before
proc, err := proc.ReadProcess(parentPid) // parentPid == 0
// after
if parentPid > 0 {
proc, err = proc.ReadProcess(parentPid)
} 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") {
// caller bug: fix the PID source rather than retrying
}
} Prevention
- Never pass sentinel 0 for 'unknown parent'; use a separate found flag
- Initialize PID fields explicitly and validate before lookup
- Skip the lookup entirely when pid <= 0
When it happens
Trigger: Calling ReadProcess (directly or via pidIdentityChanged) with pid <= 0 — e.g. an uninitialized pid variable, a zero value from a struct field, or a sentinel used to mean 'no process'.
Common situations: Caller populates the PID from a lookup that returned nothing and passes 0 through; code paths that haven't discovered the parent yet and pass 0 as the parent PID.
Related errors
- invalid pid %d
- listfds returned partial record
- launchctl blame failed: %w
- no service label found for pid %d
- process not managed by a named launchd service: %s
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/90dcb07b839d6ec3.
Report an issue: GitHub.