wavetermdev/waveterm · warning · ErrNotFound

procinfo: process not found

Error message

procinfo: process not found

What it means

procinfo.ErrNotFound is returned by GetProcInfo (and its helpers readStat/readUid) when the requested pid does not exist — i.e. /proc/<pid>/stat or /proc/<pid>/status cannot be read because the process is gone or never existed. It is a sentinel error so callers can use errors.Is to distinguish 'no such process' from other I/O failures.

Source

Thrown at pkg/util/procinfo/procinfo.go:9

// Copyright 2026, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0

package procinfo

import "errors"

// ErrNotFound is returned by GetProcInfo when the requested pid does not exist.
var ErrNotFound = errors.New("procinfo: process not found")

// LinuxStatStatus maps the single-character state from /proc/[pid]/stat to a human-readable name.
var LinuxStatStatus = map[string]string{
	"R": "running",
	"S": "sleeping",
	"D": "disk-wait",
	"Z": "zombie",
	"T": "stopped",
	"t": "tracing-stop",
	"W": "paging",
	"X": "dead",
	"x": "dead",
	"K": "wakekill",
	"P": "parked",
	"I": "idle",
}

// ProcInfo holds per-process information read from the OS.

View on GitHub (pinned to a4447c1563)

Solutions

  1. Use errors.Is(err, procinfo.ErrNotFound) to detect the missing-process case and handle it as an expected outcome.
  2. Retry once after a short delay if the process was just spawned — it may not have been fully registered yet.
  3. Verify the pid is still alive (e.g. signal 0 or /proc/<pid> existence) before calling GetProcInfo.
  4. Check permissions: if /proc/<pid>/stat is unreadable due to ownership, the same sentinel may surface.

Example fix

// before
info, err := procinfo.GetProcInfo(pid)
if err != nil {
    return err
}
// after
info, err := procinfo.GetProcInfo(pid)
if errors.Is(err, procinfo.ErrNotFound) {
    return nil // process already exited
}
if err != nil {
    return err
}
Defensive patterns

Strategy: type-guard

Validate before calling

if _, err := os.Stat(fmt.Sprintf("/proc/%d/stat", pid)); os.IsNotExist(err) {
    // pid already gone; skip GetProcInfo
}

Type guard

func isProcNotFound(err error) bool { return errors.Is(err, procinfo.ErrNotFound) }

Try / catch

info, err := procinfo.GetProcInfo(pid)
if errors.Is(err, procinfo.ErrNotFound) {
    return nil // expected race: process exited
}
if err != nil {
    return err // real I/O or permission failure
}

Prevention

When it happens

Trigger: Calling procinfo.GetProcInfo(pid) for a pid that has exited, is not owned/readable, or never existed; EnsureInitialData/InitMainServer polling a process that terminated between listing and reading its /proc entries.

Common situations: Race between finding a pid (e.g. from a child process spawn) and querying its info; short-lived worker processes that exit before status is read; querying pids from a stale process list; running in a container where /proc of the host is restricted.

Related errors


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