{"record":{"id":"05814818be0a8947","repo":"gastownhall/beads","slug":"close-verified-process-handle-for-pid-d-w","errorCode":null,"errorMessage":"close verified process handle for pid %d: %w","messagePattern":"close verified process handle for pid (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/shutdown.go","lineNumber":268,"sourceCode":"\t\t\t\t\topenErr,\n\t\t\t\t\tunverifiableProcessChecks{},\n\t\t\t\t)\n\t\t\t}\n\t\t\tif dead {\n\t\t\t\tif _, quarantineErr := quarantineRecord(rootDir, pidName, time.Now()); quarantineErr != nil {\n\t\t\t\t\tlock.Unlock()\n\t\t\t\t\treturn nil, fmt.Errorf(\"quarantine dead process record %s: %w\", recordPath, quarantineErr)\n\t\t\t\t}\n\t\t\t\treturn lock, nil\n\t\t\t}\n\t\t\tif killErr := handle.Kill(); killErr != nil {\n\t\t\t\t_ = handle.Close()\n\t\t\t\tlock.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"kill verified pid %d from %s: %w\", pf.Pid, recordPath, killErr)\n\t\t\t}\n\t\t\tif closeErr := handle.Close(); closeErr != nil {\n\t\t\t\tlock.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"close verified process handle for pid %d: %w\", pf.Pid, closeErr)\n\t\t\t}\n\t\t\twaitBudget := max(time.Until(deadline), shutdownPostKillMinimum)\n\t\t\tif waitErr := waitForRecordedProcessExit(pf, waitBudget); waitErr != nil {\n\t\t\t\tlock.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"confirm verified pid %d stopped: %w\", pf.Pid, waitErr)\n\t\t\t}\n\t\t\tif removeErr := pidfile.Remove(rootDir, pidName); removeErr != nil {\n\t\t\t\tlock.Unlock()\n\t\t\t\treturn nil, fmt.Errorf(\"remove stopped process record %s: %w\", recordPath, removeErr)\n\t\t\t}\n\t\t\treturn lock, nil\n\n\t\tcase !lockfile.IsLocked(err):\n\t\t\treturn nil, fmt.Errorf(\"probe %s: %w\", lockPath, err)\n\t\t}\n\n\t\tpf, readErr := pidfile.Read(rootDir, pidName)\n\t\tif readErr != nil {","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/shutdown.go#L250-L286","documentation":"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.","triggerScenarios":"handle.Kill() succeeded but handle.Close() returned a non-nil error during proxy.Shutdown's stopAndAcquire phase.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := proxy.Shutdown(rootDir)\nif err != nil && strings.Contains(err.Error(), \"close verified process handle\") {\n    time.Sleep(time.Second)\n    err = proxy.Shutdown(rootDir) // retry once\n}","preventionTips":["Fix file-descriptor leaks in long-running host processes.","Retry shutdown on this rare transient failure."],"tags":["process","shutdown","file-descriptor"],"backgroundTag":"process-handle-close-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}