wavetermdev/waveterm · error

procinfo: parse pid: %w

Error message

procinfo: parse pid: %w

What it means

The leading pid field of /proc/<pid>/stat (text before the first '(') failed strconv.ParseInt. Since the kernel always writes a numeric pid here, this indicates the stat content is not a genuine procfs stat record or was truncated/garbled.

Source

Thrown at pkg/util/procinfo/procinfo_linux.go:90

	comm := s[lp+1 : rp]
	rest := strings.Fields(s[rp+1:])

	// rest[0] = field 3 (state), rest[1] = field 4 (ppid), ...
	// Fields after comm are numbered starting at 3, so rest[i] = field (i+3).
	// We need:
	//   rest[0]  = field  3  state
	//   rest[1]  = field  4  ppid
	//   rest[11] = field 14  utime
	//   rest[12] = field 15  stime
	//   rest[17] = field 20  num_threads
	//   rest[21] = field 24  rss (pages)
	if len(rest) < 22 {
		return nil, fmt.Errorf("procinfo: too few fields in stat for pid %d", pid)
	}

	parsedPid, err := strconv.ParseInt(pidStr, 10, 32)
	if err != nil {
		return nil, fmt.Errorf("procinfo: parse pid: %w", err)
	}

	statusChar := rest[0]
	status, ok := LinuxStatStatus[statusChar]
	if !ok {
		status = "unknown"
	}

	info := &ProcInfo{
		Pid:        int32(parsedPid),
		Command:    comm,
		Status:     status,
		CpuUser:    -1,
		CpuSys:     -1,
		VmRSS:      -1,
		NumThreads: -1,
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Inspect the actual file content: head -c 200 /proc/<pid>/stat — it must start with the pid followed by ' ('
  2. If in tests, fix fixtures so stat lines begin with the numeric pid
  3. Verify /proc is real procfs (mount -t proc) in the deployment environment
  4. Retry the read if this occurred during heavy process churn

Example fix

// before
parsedPid, err := strconv.ParseInt(pidStr, 10, 32)
if err != nil {
    return nil, fmt.Errorf("procinfo: parse pid: %w", err)
}
// after: cross-check against the requested pid
parsedPid, err := strconv.ParseInt(pidStr, 10, 32)
if err != nil {
    return nil, fmt.Errorf("procinfo: parse pid %q from stat: %w", pidStr, err)
}
if int32(parsedPid) != pid {
    return nil, fmt.Errorf("procinfo: stat pid mismatch: got %d want %d", parsedPid, pid)
}
Defensive patterns

Strategy: validation

Validate before calling

// confirm the stat file starts with a numeric pid before deeper use
data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
if err == nil {
    idx := bytes.IndexByte(data, '(')
    if idx <= 0 {
        // no pid prefix: file is not a valid stat record
    }
}

Try / catch

_, err := procinfo.GetProcInfo(ctx, nil, pid)
if err != nil && strings.Contains(err.Error(), "parse pid") {
    // stat content is not genuine procfs output; check /proc mounting and fixtures
}

Prevention

When it happens

Trigger: Malformed or fixture-supplied stat data where the text before '(' is empty or non-numeric; corrupted procfs reads; a bind-mounted fake /proc directory.

Common situations: Unit tests with hand-written stat fixtures that omit the pid; containers with a non-procfs /proc; disk/kernel-level corruption (extremely rare).

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/8140f738807880c4. Report an issue: GitHub.