{"record":{"id":"8dcbed4e2b430735","repo":"gastownhall/beads","slug":"procid-terminate-process-w","errorCode":null,"errorMessage":"procid: terminate process: %w","messagePattern":"procid: terminate process: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/procid/procid_windows.go","lineNumber":87,"sourceCode":"\t\treturn nil, fmt.Errorf(\"procid: process %d does not match token\", pid)\n\t}\n\treturn &Handle{process: process, token: tok}, nil\n}\n\nfunc (h *Handle) Signal(os.Signal) error {\n\tif err := h.verify(); err != nil {\n\t\tif errors.Is(err, errProcessExited) {\n\t\t\t// The target exited on its own after Open; termination's goal is\n\t\t\t// already met.\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\tif err := windows.TerminateProcess(h.process, 1); err != nil {\n\t\tif _, exitedErr := tokenForProcess(h.process); errors.Is(exitedErr, errProcessExited) {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"procid: terminate process: %w\", err)\n\t}\n\treturn nil\n}\n\nfunc (h *Handle) Kill() error { return h.Signal(os.Kill) }\n\nfunc (h *Handle) Close() error {\n\tif h.process == 0 {\n\t\treturn nil\n\t}\n\terr := windows.CloseHandle(h.process)\n\th.process = 0\n\tif err != nil {\n\t\treturn fmt.Errorf(\"procid: close process handle: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/procid/procid_windows.go#L69-L105","documentation":"Handle.Signal called windows.TerminateProcess and it failed. Before returning the error, the code re-checks liveness: if the process actually exited in the meantime (errProcessExited), termination's goal is met and nil is returned; only genuine termination failures (access denied, handle invalid for another reason) are wrapped with this message.","triggerScenarios":"Calling Handle.Signal/Kill when TerminateProcess fails with an error other than \"process exited between the liveness check and the kill\" — typically ERROR_ACCESS_DENIED on a protected process.","commonSituations":"Killing a process running as another user or elevated while the caller is not; target protected by antivirus/EDR; killing a system-critical process.","solutions":["Check errors.Is(err, windows.ERROR_ACCESS_DENIED); run elevated or take ownership of the target process lifecycle","Confirm the process wasn't protected by security software and adjust policy or target the right process","Re-open with Open and retry once, in case the handle became stale","If termination is best-effort, treat non-access-denied failures as fatal and alert instead of silently ignoring"],"exampleFix":"// before\nif err := h.Kill(); err != nil { return err }\n// after\nif err := h.Kill(); err != nil {\n    if errors.Is(err, windows.ERROR_ACCESS_DENIED) {\n        return fmt.Errorf(\"kill %d: need elevated rights: %w\", pid, err)\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// Confirm we can open with terminate rights before keeping a long-lived handle\nh, err := procid.Open(pid, tok)\nif err != nil {\n    return err // surfaces ERROR_ACCESS_DENIED early, before kill time\n}","typeGuard":"func canTerminate(pid int, tok procid.Token) bool {\n    h, err := procid.Open(pid, tok)\n    if err != nil { return false }\n    _ = h.Close()\n    return true\n}","tryCatchPattern":"if err := h.Kill(); err != nil {\n    if errors.Is(err, windows.ERROR_ACCESS_DENIED) {\n        return fmt.Errorf(\"kill: insufficient privileges: %w\", err)\n    }\n    return err // note: already-exited targets return nil from Signal\n}","preventionTips":["Open the handle (with PROCESS_TERMINATE) early to fail fast on privilege problems","Run the killing component under an account that owns or can control the target","Treat Signal returning nil as 'goal met' — it already handles exited targets","Keep antivirus/EDR exclusions in mind when killing child processes"],"tags":["windows","process","kill","permissions"],"backgroundTag":"terminate-process-access-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}