{"record":{"id":"297ed8069a004739","repo":"gastownhall/beads","slug":"open-process-d-w","errorCode":null,"errorMessage":"open process %d: %w","messagePattern":"open process (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/unverified_process_windows.go","lineNumber":38,"sourceCode":"// from recycling the PID underneath us.\ntype unverifiedProcess struct {\n\tpid    int\n\thandle windows.Handle\n}\n\n// openUnverifiedProcess opens a stable handle for pid. gone reports a PID\n// that no longer exists or has already terminated.\nfunc openUnverifiedProcess(pid int) (proc *unverifiedProcess, gone bool, err error) {\n\thandle, err := windows.OpenProcess(\n\t\twindows.PROCESS_QUERY_LIMITED_INFORMATION|windows.PROCESS_TERMINATE,\n\t\tfalse,\n\t\tuint32(pid),\n\t)\n\tif err != nil {\n\t\tif errors.Is(err, windows.ERROR_INVALID_PARAMETER) {\n\t\t\treturn nil, true, nil\n\t\t}\n\t\treturn nil, false, fmt.Errorf(\"open process %d: %w\", pid, err)\n\t}\n\texited, err := handleExited(handle)\n\tif err != nil {\n\t\t_ = windows.CloseHandle(handle)\n\t\treturn nil, false, err\n\t}\n\tif exited {\n\t\t_ = windows.CloseHandle(handle)\n\t\treturn nil, true, nil\n\t}\n\treturn &unverifiedProcess{pid: pid, handle: handle}, false, nil\n}\n\nfunc (p *unverifiedProcess) executableBasename() (basename string, gone bool, err error) {\n\tbuffer := make([]uint16, 32768)\n\tsize := uint32(len(buffer))\n\tif err := windows.QueryFullProcessImageName(p.handle, 0, &buffer[0], &size); err != nil {\n\t\treturn \"\", false, fmt.Errorf(\"query image name for pid %d: %w\", p.pid, err)","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/unverified_process_windows.go#L20-L56","documentation":"On Windows, openUnverifiedProcess opens a handle to the PID via OpenProcess to inspect it before any kill. ERROR_INVALID_PARAMETER is treated as 'process gone'; any other OpenProcess failure is wrapped in this error, aborting the force-stop so the proxy never acts on an unverified PID.","triggerScenarios":"openUnverifiedProcess calls windows.OpenProcess and receives an error other than ERROR_INVALID_PARAMETER — most commonly ERROR_ACCESS_DENIED (process owned by another user/service, e.g. a recycled PID now owned by SYSTEM).","commonSituations":"The recorded daemon PID was recycled by a Windows service or another user's process (access denied); running without elevation when the daemon ran elevated; antivirus/EDR blocking handle opens.","solutions":["Run the stop command from an elevated (Administrator) terminal after confirming the PID's identity in Task Manager or `tasklist /FI \"PID eq <pid>\"`.","If the PID was recycled to an unrelated process, do not kill it — delete the stale pidfile and restart.","Check antivirus/EDR policies that block OpenProcess and add an exclusion for bd.","Reboot or log off stale sessions to clear recycled-PID conflicts, then retry."],"exampleFix":"// before: access denied opening elevated daemon's PID\n# run non-elevated\nbd ...\n// after: elevated terminal\nStart-Process -Verb RunAs bd ... # or taskkill /PID <pid> /F after verifying","handlingStrategy":"try-catch","validationCode":"out, err := exec.Command(\"tasklist\", \"/FI\", fmt.Sprintf(\"PID eq %d\", pid), \"/FO\", \"CSV\", \"/NH\").Output()\nif err == nil && !strings.Contains(string(out), expectedImageName) {\n    // PID recycled to an unrelated process: do not open/kill\n}","typeGuard":null,"tryCatchPattern":"proc, gone, err := openUnverifiedProcess(pid)\nif err != nil {\n    if errors.Is(err, windows.ERROR_ACCESS_DENIED) {\n        // needs elevation or PID owned by another user: verify first\n    }\n    return err\n}","preventionTips":["Stop daemons from the same user (and elevation level) that started them.","Verify PID identity with tasklist before escalating privileges.","Add antivirus/EDR exclusions for bd so OpenProcess is not blocked.","Delete stale pidfiles after crashes or reboots to avoid recycled-PID conflicts."],"tags":["go","windows","openprocess","process-inspection","permissions"],"backgroundTag":"process-inspection-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}