wavetermdev/waveterm · error
procinfo: Uid line not found in %s
Error message
procinfo: Uid line not found in %s
What it means
readUid parses /proc/<pid>/status looking for the 'Uid:' line; if the file is exhausted without finding it, it returns this error. It means the process's status file did not contain a UID entry, so the process owner could not be determined. Thrown because procinfo cannot fabricate a valid uid and will not silently return 0.
Source
Thrown at pkg/util/procinfo/procinfo_linux.go:153
return 0, ErrNotFound
}
return 0, fmt.Errorf("procinfo: read %s: %w", path, err)
}
for _, line := range strings.Split(string(data), "\n") {
if !strings.HasPrefix(line, "Uid:") {
continue
}
fields := strings.Fields(line)
if len(fields) < 2 {
break
}
uid, err := strconv.ParseUint(fields[1], 10, 32)
if err != nil {
break
}
return uint32(uid), nil
}
return 0, fmt.Errorf("procinfo: Uid line not found in %s", path)
}
View on GitHub (pinned to a4447c1563)
Solutions
- Check the pid still exists (os.Stat /proc/<pid>) before calling GetProcInfo and treat this error as 'process gone'
- Skip kernel threads / pids whose status has no Uid line instead of failing the whole operation
- Verify /proc is mounted normally and not masked (hidepid=2, containers need /proc/status readable)
- Wrap the call to tolerate this error and default the uid (e.g. to 0 or the current user) when non-fatal
Example fix
// before
info, err := procinfo.GetProcInfo(ctx, snap, pid)
if err != nil {
return err
}
// after
info, err := procinfo.GetProcInfo(ctx, snap, pid)
if err != nil {
if strings.Contains(err.Error(), "Uid line not found") || errors.Is(err, procinfo.ErrNotFound) {
return nil // process vanished or kernel thread; skip it
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
pidPath := fmt.Sprintf("/proc/%d/status", pid)
if _, err := os.Stat(pidPath); err != nil {
// process gone; skip call
} Type guard
func procStatusReadable(pid int32) bool {
f, err := os.Open(fmt.Sprintf("/proc/%d/status", pid))
if err != nil { return false }
defer f.Close()
data, err := io.ReadAll(f)
return err == nil && strings.Contains(string(data), "Uid:")
} Try / catch
info, err := procinfo.GetProcInfo(ctx, snap, pid)
if err != nil {
if strings.Contains(err.Error(), "Uid line not found") {
continue // skip vanished/kernel process
}
return err
} Prevention
- Re-check /proc/<pid> existence right before enriching a pid
- Treat missing Uid/status as a transient race, not a fatal error
- Verify /proc is not masked (containers, hidepid) before bulk enumeration
- Skip pid 2 (kthreadd) descendants / kernel threads
When it happens
Trigger: Calling GetProcInfo for a pid whose /proc/<pid>/status lacks a 'Uid:' line — e.g. the process exited between listing and read (file now empty or gone), a kernel thread (kthreadd children have no Uid line), or a file read from a non-standard /proc mount.
Common situations: Race conditions with short-lived processes during snapshot enrichment; container environments with masked or minimal /proc (hidepid, seccomp filters); reading status for kernel threads; malformed or mocked /proc in tests.
Related errors
- procinfo: process not found
- procinfo: read %s: %w
- procinfo: malformed stat for pid %d
- procinfo: too few fields in stat for pid %d
- procinfo: parse pid: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/5081beddcfb3b647.
Report an issue: GitHub.