{"record":{"id":"8dd4467172931821","repo":"uutils/coreutils","slug":"error-no-such-process","errorCode":null,"errorMessage":"error-no-such-process","messagePattern":"error-no-such-process","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"warning","filePath":"src/uucore/src/lib/features/process/windows.rs","lineNumber":481,"sourceCode":"        Disposition::Probe => match sys::wait_for_one(child.as_handle(), 0)? {\n            sys::WaitOutcome::TimedOut => Ok(()),\n            // The process has exited: the POSIX analog is ESRCH.\n            sys::WaitOutcome::Object(_) => Err(io::ErrorKind::NotFound.into()),\n        },\n        Disposition::Ignore => Ok(()),\n        Disposition::Interrupt | Disposition::Terminate => {\n            terminate_with_signal(child.as_handle(), signal)\n        }\n    }\n}\n\nconst PROBE_ACCESS: u32 = PROCESS_SYNCHRONIZE;\n// SYNCHRONIZE tells \"already exited\" apart from a real denial after a failed\n// TerminateProcess (both report ERROR_ACCESS_DENIED).\nconst TERMINATE_ACCESS: u32 = PROCESS_TERMINATE | PROCESS_SYNCHRONIZE;\n\nfn no_such_process() -> io::Error {\n    io::Error::new(io::ErrorKind::NotFound, translate!(\"error-no-such-process\"))\n}\n\n/// A process handle becomes signaled when the process exits.\nfn has_exited(handle: BorrowedHandle) -> io::Result<bool> {\n    Ok(matches!(\n        sys::wait_for_one(handle, 0)?,\n        sys::WaitOutcome::Object(_)\n    ))\n}\n\n/// Request `SeDebugPrivilege` once per process; with it, opening a process\n/// bypasses the target's security descriptor.\n///\n/// Silent and best-effort: only an elevated administrator's token holds the\n/// privilege, and tokens without it are left untouched.\npub fn enable_debug_privilege() {\n    static REQUESTED: OnceLock<()> = OnceLock::new();\n    REQUESTED.get_or_init(|| {","sourceCodeStart":463,"sourceCodeEnd":499,"githubUrl":"https://github.com/uutils/coreutils/blob/92995feca29e324a7c559ede91db81c32d9f5d59/src/uucore/src/lib/features/process/windows.rs#L463-L499","documentation":"On Windows, process termination code constructs a NotFound io::Error with the localized 'error-no-such-process' message when it can be established that the target PID has already exited. probe_pid distinguishes 'already exited' from access denial using PROBE_ACCESS (PROCESS_SYNCHRONIZE).","triggerScenarios":"Calling kill/terminate on a PID that no longer exists, or a PID whose process exited between lookup and TerminateProcess (the subsequent ERROR_ACCESS_DENIED is disambiguated by probing with PROCESS_SYNCHRONIZE).","commonSituations":"Race conditions when killing short-lived processes; scripts computing PIDs from stale data; retry loops signaling processes that already finished.","solutions":["Treat this NotFound error as success when the goal was termination","Check existence first (probe the PID) before signaling","Re-enumerate the process list to get a fresh PID"],"exampleFix":"// before\nkill(pid)?;\n// after\nif let Err(e) = kill(pid) { if e.kind() != io::ErrorKind::NotFound { return Err(e); } }","handlingStrategy":"try-catch","validationCode":"// windows: check existence before signaling\nfn pid_alive(pid: u32) -> bool {\n    std::process::Command::new(\"tasklist\").args([\"/FI\", &format!(\"PID eq {pid}\")]).output().map(|o| o.status.success()).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match kill(pid) {\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound => { /* already exited: treat as success */ }\n    r => r?,\n}","preventionTips":["Treat NotFound from kill as a benign outcome","Avoid caching PIDs across long-running scripts","Re-read the process list right before signaling"],"tags":["windows","process","kill","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"92995feca29e324a7c559ede91db81c32d9f5d59","analyzedAt":"2026-09-20T12:39:35.476Z","contentChangedAt":"2026-09-20T12:39:35.476Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}