gastownhall/beads · error
close verified process handle for pid %d: %w
Error message
close verified process handle for pid %d: %w
What it means
After successfully killing the verified recorded process, stopAndAcquire tried to release the OS process handle and that Close() failed. This is a rare resource-cleanup failure on the handle obtained by openRecordedProcess; Shutdown aborts so the failure is visible instead of silently leaking the handle.
Source
Thrown at internal/storage/dbproxy/proxy/shutdown.go:268
openErr,
unverifiableProcessChecks{},
)
}
if dead {
if _, quarantineErr := quarantineRecord(rootDir, pidName, time.Now()); quarantineErr != nil {
lock.Unlock()
return nil, fmt.Errorf("quarantine dead process record %s: %w", recordPath, quarantineErr)
}
return lock, nil
}
if killErr := handle.Kill(); killErr != nil {
_ = handle.Close()
lock.Unlock()
return nil, fmt.Errorf("kill verified pid %d from %s: %w", pf.Pid, recordPath, killErr)
}
if closeErr := handle.Close(); closeErr != nil {
lock.Unlock()
return nil, fmt.Errorf("close verified process handle for pid %d: %w", pf.Pid, closeErr)
}
waitBudget := max(time.Until(deadline), shutdownPostKillMinimum)
if waitErr := waitForRecordedProcessExit(pf, waitBudget); waitErr != nil {
lock.Unlock()
return nil, fmt.Errorf("confirm verified pid %d stopped: %w", pf.Pid, waitErr)
}
if removeErr := pidfile.Remove(rootDir, pidName); removeErr != nil {
lock.Unlock()
return nil, fmt.Errorf("remove stopped process record %s: %w", recordPath, removeErr)
}
return lock, nil
case !lockfile.IsLocked(err):
return nil, fmt.Errorf("probe %s: %w", lockPath, err)
}
pf, readErr := pidfile.Read(rootDir, pidName)
if readErr != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped error for EBADF/EMFILE — look for descriptor leaks in the calling application.
- Retry the shutdown; Close failures are frequently transient.
- Report upstream if reproducible: handle.Close() failing after a successful Kill is unexpected.
Defensive patterns
Strategy: retry
Try / catch
err := proxy.Shutdown(rootDir)
if err != nil && strings.Contains(err.Error(), "close verified process handle") {
time.Sleep(time.Second)
err = proxy.Shutdown(rootDir) // retry once
} Prevention
- Fix file-descriptor leaks in long-running host processes.
- Retry shutdown on this rare transient failure.
When it happens
Trigger: handle.Kill() succeeded but handle.Close() returned a non-nil error during proxy.Shutdown's stopAndAcquire phase.
Common situations: Very rare OS-level handle/file-descriptor cleanup failures (mostly seen on Windows with process handles); typically indicates descriptor-table exhaustion (EMFILE/EBADF) in a long-running process.
Related errors
- ErrUnverifiableProcess
- kill verified pid %d from %s: %w
- confirm verified pid %d stopped: %w
- pidfile: invalid pid
- errStartInterrupted
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/05814818be0a8947.
Report an issue: GitHub.