wavetermdev/waveterm · error

procinfo: GetProcInfo requires a snapshot on windows

Error message

procinfo: GetProcInfo requires a snapshot on windows

What it means

GetProcInfo on Windows requires the caller to pass the snapshot object returned by MakeGlobalSnapshot as the snap parameter; passing nil makes per-pid lookup impossible, so it returns this error immediately. The snapshot-based design avoids expensive per-pid opens on Windows.

Source

Thrown at pkg/util/procinfo/procinfo_windows.go:84

			exeName:    windows.UTF16ToString(entry.ExeFile[:]),
		}
		if err := windows.Process32Next(snap, &entry); err != nil {
			if errors.Is(err, windows.ERROR_NO_MORE_FILES) {
				break
			}
			return nil, fmt.Errorf("procinfo: Process32Next: %w", err)
		}
	}

	return &windowsSnapshot{procs: procs}, nil
}

// GetProcInfo returns a ProcInfo for the given pid.
// snap must be a non-nil value returned by MakeGlobalSnapshot.
// Returns nil, nil if the pid is not present in the snapshot.
func GetProcInfo(_ context.Context, snap any, pid int32) (*ProcInfo, error) {
	if snap == nil {
		return nil, fmt.Errorf("procinfo: GetProcInfo requires a snapshot on windows")
	}
	ws, ok := snap.(*windowsSnapshot)
	if !ok {
		return nil, fmt.Errorf("procinfo: invalid snapshot type")
	}
	si, found := ws.procs[pid]
	if !found {
		return nil, ErrNotFound
	}

	info := &ProcInfo{
		Pid:        pid,
		Ppid:       int32(si.ppid),
		NumThreads: int32(si.numThreads),
		Command:    si.exeName,
		CpuUser:    -1,
		CpuSys:     -1,
		VmRSS:      -1,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Call MakeGlobalSnapshot first and pass its return value (not nil) as snap
  2. Check the error from MakeGlobalSnapshot before using the snapshot
  3. Cache the snapshot for the duration of the batch of GetProcInfo calls
  4. On non-Windows platforms this error does not apply; guard platform-specific code paths

Example fix

// before
info, _ := procinfo.GetProcInfo(ctx, cachedSnap, pid) // cachedSnap may be nil
// after
if cachedSnap == nil {
	cachedSnap, err = procinfo.MakeGlobalSnapshot()
	if err != nil {
		return err
	}
}
info, err := procinfo.GetProcInfo(ctx, cachedSnap, pid)
Defensive patterns

Strategy: validation

Validate before calling

if snap == nil {
	s, err := procinfo.MakeGlobalSnapshot()
	if err != nil { return err }
	snap = s
}

Type guard

func hasSnapshot(snap any) bool { return snap != nil }

Try / catch

info, err := procinfo.GetProcInfo(ctx, snap, pid)
if err != nil {
	if strings.Contains(err.Error(), "requires a snapshot") {
		return fmt.Errorf("call MakeGlobalSnapshot before GetProcInfo")
	}
	return err
}

Prevention

When it happens

Trigger: Calling GetProcInfo(ctx, nil, pid) — forgetting to create or retain the result of MakeGlobalSnapshot, or a variable that was never assigned because an earlier MakeGlobalSnapshot error path set it to nil.

Common situations: Ignoring the error from MakeGlobalSnapshot and using the nil snapshot anyway; struct fields holding the snapshot left uninitialized; passing nil in tests or when porting Linux code that has no snapshot parameter.

Related errors


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