{"record":{"id":"bcfc0e6983ac29a7","repo":"gastownhall/beads","slug":"close-verified-backend-process-handle-for-pid-d","errorCode":null,"errorMessage":"close verified backend process handle for pid %d: %w","messagePattern":"close verified backend process handle for pid (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/endpoint.go","lineNumber":843,"sourceCode":"\t\t\terr,\n\t\t\tunverifiableProcessChecks{},\n\t\t)\n\t}\n\tif dead {\n\t\tif _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {\n\t\t\treturn fmt.Errorf(\"quarantine dead backend record: %w\", err)\n\t\t}\n\t\treturn nil\n\t}\n\tif err := handle.Kill(); err != nil {\n\t\t_ = handle.Close()\n\t\treturn fmt.Errorf(\"kill verified orphan backend pid %d from %s: %w\", pf.Pid, recordPath, err)\n\t}\n\t// Close before waiting: an open handle on Windows keeps the dead PID\n\t// allocated, so procid.Verify would keep matching it and the exit wait\n\t// below would always time out.\n\tif err := handle.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close verified backend process handle for pid %d: %w\", pf.Pid, err)\n\t}\n\tif err := waitForRecordedProcessExit(pf, backendExitTimeout); err != nil {\n\t\treturn fmt.Errorf(\"wait for verified orphan backend pid %d: %w\", pf.Pid, err)\n\t}\n\tif _, err := quarantineRecord(rootDir, server.PIDFileName, time.Now()); err != nil {\n\t\treturn fmt.Errorf(\"quarantine orphan backend record: %w\", err)\n\t}\n\treturn nil\n}\n\ntype unverifiableProcessChecks struct {\n\tLiveEstablished bool\n\tLegacyProxy     bool\n}\n\nfunc unverifiableProcessError(\n\toperation string,\n\trecordPath string,","sourceCodeStart":825,"sourceCodeEnd":861,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/endpoint.go#L825-L861","documentation":"After successfully killing the verified orphan backend, cleanup closes the OS process handle before waiting for exit (on Windows an open handle keeps the PID allocated, breaking exit verification). This error wraps a handle.Close() failure — the handle could not be released, so cleanup aborts rather than risk a misleading exit-wait.","triggerScenarios":"handle.Kill() succeeded but handle.Close() returns an error at internal/storage/dbproxy/proxy/endpoint.go:842-843 (OS-level handle release failure).","commonSituations":"OS handle-table pressure or duplicated handle ownership on Windows; driver/runtime errors closing the process handle; rare resource-exhaustion conditions (too many open handles).","solutions":["Retry the cleanup once — handle close failures are usually transient OS conditions.","Check system handle usage (Task Manager / handle.exe on Windows) and close leaking processes.","Reboot or free OS resources if handle exhaustion is indicated.","As a last resort, since Kill already succeeded, wait for the pid to disappear, then manually quarantine: mv <recordPath> <recordPath>.stale-<unix-ts>."],"exampleFix":"// before\nError: close verified backend process handle for pid 4242: os: process already finished\n// after\n$ ps -p 4242 || true   # confirm dead\n$ mv /ws/.beads/dbproxy/dolt-backend.pid /ws/.beads/dbproxy/dolt-backend.pid.stale-$(date +%s)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var retried bool\nretry:\n    if err := cleanupOrphanBackend(rootDir); err != nil && strings.Contains(err.Error(), \"close verified backend process handle\") && !retried {\n        retried = true\n        time.Sleep(500 * time.Millisecond)\n        goto retry\n    }","preventionTips":["Retry once — handle-close failures are typically transient.","On Windows, watch for handle leaks with handle.exe / Process Explorer.","Keep OS resource limits healthy (few stale processes/handles).","Since Kill already succeeded, verify the pid is dead before manual quarantine."],"tags":["go","process-handle","windows","resource-cleanup"],"backgroundTag":"process-handle-close-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}