gastownhall/beads · error
kill verified orphan backend pid %d from %s: %w
Error message
kill verified orphan backend pid %d from %s: %w
What it means
Cleanup verified the recorded PID as this workspace's orphaned backend and attempted to kill it. This error wraps a failure of handle.Kill() on that process handle — the orphan backend could not be terminated, so the stale record is left un-quarantined and cleanup aborts.
Source
Thrown at internal/storage/dbproxy/proxy/endpoint.go:837
handle, dead, err := openRecordedProcess(pf)
if err != nil {
return unverifiableProcessError(
"backend cleanup",
recordPath,
pf.Pid,
err,
unverifiableProcessChecks{},
)
}
if dead {
if _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {
return fmt.Errorf("quarantine dead backend record: %w", err)
}
return nil
}
if err := handle.Kill(); err != nil {
_ = handle.Close()
return fmt.Errorf("kill verified orphan backend pid %d from %s: %w", pf.Pid, recordPath, err)
}
// Close before waiting: an open handle on Windows keeps the dead PID
// allocated, so procid.Verify would keep matching it and the exit wait
// below would always time out.
if err := handle.Close(); err != nil {
return fmt.Errorf("close verified backend process handle for pid %d: %w", pf.Pid, err)
}
if err := waitForRecordedProcessExit(pf, backendExitTimeout); err != nil {
return fmt.Errorf("wait for verified orphan backend pid %d: %w", pf.Pid, err)
}
if _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {
return fmt.Errorf("quarantine orphan backend record: %w", err)
}
return nil
}
type unverifiableProcessChecks struct {
LiveEstablished boolView on GitHub (pinned to 71377f2769)
Solutions
- Kill the process manually with elevated privileges: kill -9 <pid> (or Stop-Process -Force -Id <pid> on Windows).
- Run the cleanup under the same user (or via sudo) that started the backend.
- Confirm with ps/tasklist whether the process already exited; if it is gone, quarantine the record manually and retry.
- Check container/sandbox policies if signals are being blocked.
Example fix
// before Error: kill verified orphan backend pid 4242 from /ws/.beads/dbproxy/dolt-backend.pid: operation not permitted // after $ sudo kill -9 4242 $ mv /ws/.beads/dbproxy/dolt-backend.pid /ws/.beads/dbproxy/dolt-backend.pid.stale-$(date +%s)
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check you may signal the recorded pid before invoking cleanup:
if proc, err := os.FindProcess(pid); err == nil {
_ = proc.Signal(syscall.Signal(0)) // EPERM here predicts kill failure
} Type guard
func canSignal(pid int) bool {
p, err := os.FindProcess(pid)
if err != nil { return false }
return p.Signal(syscall.Signal(0)) == nil
} Try / catch
if err := cleanupOrphanBackend(rootDir); err != nil && strings.Contains(err.Error(), "kill verified orphan backend pid") {
// escalate: run cleanup under the backend's owning user or with sudo,
// or kill -9 <pid> manually, then quarantine the record
} Prevention
- Start backends and run bd under the same user account.
- Avoid launching backends via sudo.
- In containers, run cleanup inside the same container/PID namespace.
- Grant signal rights (Windows: same user/elevated shell) for service-owned processes.
When it happens
Trigger: openRecordedProcess returned a live handle matching pf, handle.Kill() returns an error at internal/storage/dbproxy/proxy/endpoint.go:835-837 (e.g. insufficient privileges, access denied, process already terminating with a handle error).
Common situations: The orphan backend runs as a different user (e.g. started via sudo) so the current user may not signal it; on Windows, access-denied from OpenProcess-protected processes; hardened containers/seccomp blocking signals.
Related errors
- dolt path is not executable
- failed to create backup directory: %w
- failed to create temp file: %w
- failed to create backup file: %w
- %d artifact(s) could not be removed
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c14df78e75544c42.
Report an issue: GitHub.