wavetermdev/waveterm · error
procinfo: Process32First: %w
Error message
procinfo: Process32First: %w
What it means
After the snapshot is created, Process32First retrieves the first process entry; failure is wrapped in this error. It indicates the snapshot handle exists but its first entry could not be read — an essentially unrecoverable snapshot state.
Source
Thrown at pkg/util/procinfo/procinfo_windows.go:59
type windowsSnapshot struct {
procs map[int32]*snapInfo
}
// MakeGlobalSnapshot enumerates all processes once via CreateToolhelp32Snapshot.
func MakeGlobalSnapshot() (any, error) {
snap, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPPROCESS, 0)
if err != nil {
return nil, fmt.Errorf("procinfo: CreateToolhelp32Snapshot: %w", err)
}
defer windows.CloseHandle(snap)
procs := make(map[int32]*snapInfo)
var entry windows.ProcessEntry32
entry.Size = uint32(unsafe.Sizeof(entry))
if err := windows.Process32First(snap, &entry); err != nil {
return nil, fmt.Errorf("procinfo: Process32First: %w", err)
}
for {
pid := int32(entry.ProcessID)
procs[pid] = &snapInfo{
ppid: entry.ParentProcessID,
numThreads: entry.Threads,
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
}View on GitHub (pinned to a4447c1563)
Solutions
- Ensure the underlying entry.Size is set to uint32(unsafe.Sizeof(entry)) before the call (library already does this; check vendored forks)
- Inspect the wrapped win32 error (errors.Is on windows.ERROR_ACCESS_DENIED etc.)
- Retry MakeGlobalSnapshot once — the failure is usually transient or environmental
- Update the golang.org/x/sys/windows package if the version has known Process32First bugs
Example fix
// after (caller retry pattern)
var snap any
var err error
for i := 0; i < 2; i++ {
snap, err = procinfo.MakeGlobalSnapshot()
if err == nil {
break
}
}
if err != nil {
return fmt.Errorf("process snapshot unavailable: %w", err)
} Defensive patterns
Strategy: retry
Try / catch
snap, err := procinfo.MakeGlobalSnapshot()
if err != nil {
if strings.Contains(err.Error(), "Process32First") {
snap, err = procinfo.MakeGlobalSnapshot() // single retry
}
if err != nil { return err }
} Prevention
- Keep golang.org/x/sys/windows up to date
- Never modify the ProcessEntry32 Size initialization in vendored code
- Retry snapshot creation on first-entry failure
- Report persistent failures with the wrapped win32 error code
When it happens
Trigger: MakeGlobalSnapshot when windows.Process32First fails on the fresh snapshot handle — almost always caused by an invalid/zeroed ProcessEntry32 (missing Size initialization) or an already-invalidated snapshot handle.
Common situations: Copy-pasted ProcessEntry32 declarations that forget entry.Size = uint32(unsafe.Sizeof(entry)); interference from security software invalidating the handle; extremely rare corruption during heavy process churn.
Related errors
- procinfo: CreateToolhelp32Snapshot: %w
- procinfo: Process32Next: %w
- --pid flag is not supported on Windows
- failed to create WSL command
- failed to start command: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f09383e30f118d41.
Report an issue: GitHub.