{"record":{"id":"907d7abe3330aeea","repo":"affaan-m/ECC","slug":"taskkill-exited-with-status-status","errorCode":null,"errorMessage":"taskkill exited with status {status}","messagePattern":"taskkill exited with status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ecc2/src/session/manager.rs","lineNumber":3618,"sourceCode":"#[cfg(unix)]\nfn kill_process(pid: u32) -> Result<()> {\n    send_signal(pid, libc::SIGTERM)?;\n    std::thread::sleep(std::time::Duration::from_millis(1200));\n    send_signal(pid, libc::SIGKILL)?;\n    Ok(())\n}\n\n#[cfg(windows)]\nfn kill_process(pid: u32) -> Result<()> {\n    let status = std::process::Command::new(\"taskkill\")\n        .args([\"/PID\", &pid.to_string(), \"/T\", \"/F\"])\n        .status()\n        .with_context(|| format!(\"Failed to invoke taskkill for process {pid}\"))?;\n\n    if status.success() {\n        Ok(())\n    } else {\n        Err(anyhow::anyhow!(\"taskkill exited with status {status}\"))\n    }\n}\n\n#[cfg(unix)]\nfn send_signal(pid: u32, signal: i32) -> Result<()> {\n    let outcome = unsafe { libc::kill(pid as i32, signal) };\n    if outcome == 0 {\n        return Ok(());\n    }\n\n    let error = std::io::Error::last_os_error();\n    if error.raw_os_error() == Some(libc::ESRCH) {\n        return Ok(());\n    }\n\n    Err(error).with_context(|| format!(\"Failed to kill process {pid}\"))\n}\n","sourceCodeStart":3600,"sourceCodeEnd":3636,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/ecc2/src/session/manager.rs#L3600-L3636","documentation":"On Windows, session stop invokes taskkill /PID <pid>; when the command runs but exits non-zero (process already gone, access denied), the status code is wrapped in this error. It reports the raw ExitStatus rather than a friendly reason.","triggerScenarios":"Calling stop_session on Windows where the target pid no longer exists (already exited), the caller lacks permission to kill it, or taskkill is not on PATH so status reflects invocation failure context.","commonSituations":"Stopping an already-finished session; stale pid recorded in the DB after a crash; running without sufficient privileges to terminate the child.","solutions":["Check the process still exists (tasklist /FI \"PID eq <pid>\") before taskkill, and treat 'not found' as success","Run taskkill with /F /T and inspect the exit code; if access denied, elevate or kill from the owning user","Prefer recording the actual taskkill stderr in the error message for diagnosis"],"exampleFix":"// before\nErr(anyhow::anyhow!(\"taskkill exited with status {status}\"))\n// after\nif !status.success() {\n    anyhow::bail!(\"taskkill exited with status {status} for process {pid} (process may have already exited)\");\n}","handlingStrategy":"try-catch","validationCode":"// Windows: confirm process exists before killing\nlet out = Command::new(\"tasklist\").args([\"/FI\", &format!(\"PID eq {pid}\")]).output()?;\nif !String::from_utf8_lossy(&out.stdout).contains(&pid.to_string()) {\n    return Ok(()); // already gone\n}","typeGuard":null,"tryCatchPattern":"match stop_session_windows(pid) {\n    Ok(()) => (),\n    Err(e) if e.to_string().contains(\"taskkill exited\") => {\n        eprintln!(\"kill failed for {pid}; process may already be gone\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Treat 'process not found' on kill as success (idempotent stop)","Run with adequate privileges to terminate child processes","Use /F /T flags so child trees are killed too"],"tags":["rust","windows","process-kill","taskkill"],"backgroundTag":"process-termination-failed","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}