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

  1. Check the pid still exists (os.Stat /proc/<pid>) before calling GetProcInfo and treat this error as 'process gone'
  2. Skip kernel threads / pids whose status has no Uid line instead of failing the whole operation
  3. Verify /proc is mounted normally and not masked (hidepid=2, containers need /proc/status readable)
  4. 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

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


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