affaan-m/ECC · error

taskkill exited with status

Error message

taskkill exited with status {status}

What it means

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.

Solutions

  1. Check the process still exists (tasklist /FI "PID eq <pid>") before taskkill, and treat 'not found' as success
  2. Run taskkill with /F /T and inspect the exit code; if access denied, elevate or kill from the owning user
  3. Prefer recording the actual taskkill stderr in the error message for diagnosis

Example fix

// before
Err(anyhow::anyhow!("taskkill exited with status {status}"))
// after
if !status.success() {
    anyhow::bail!("taskkill exited with status {status} for process {pid} (process may have already exited)");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Windows: confirm process exists before killing
let out = Command::new("tasklist").args(["/FI", &format!("PID eq {pid}")]).output()?;
if !String::from_utf8_lossy(&out.stdout).contains(&pid.to_string()) {
    return Ok(()); // already gone
}

Try / catch

match stop_session_windows(pid) {
    Ok(()) => (),
    Err(e) if e.to_string().contains("taskkill exited") => {
        eprintln!("kill failed for {pid}; process may already be gone");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: Stopping an already-finished session; stale pid recorded in the DB after a crash; running without sufficient privileges to terminate the child.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/907d7abe3330aeea. Report an issue: GitHub.

Appendix: source

Thrown at ecc2/src/session/manager.rs:3618

#[cfg(unix)]
fn kill_process(pid: u32) -> Result<()> {
    send_signal(pid, libc::SIGTERM)?;
    std::thread::sleep(std::time::Duration::from_millis(1200));
    send_signal(pid, libc::SIGKILL)?;
    Ok(())
}

#[cfg(windows)]
fn kill_process(pid: u32) -> Result<()> {
    let status = std::process::Command::new("taskkill")
        .args(["/PID", &pid.to_string(), "/T", "/F"])
        .status()
        .with_context(|| format!("Failed to invoke taskkill for process {pid}"))?;

    if status.success() {
        Ok(())
    } else {
        Err(anyhow::anyhow!("taskkill exited with status {status}"))
    }
}

#[cfg(unix)]
fn send_signal(pid: u32, signal: i32) -> Result<()> {
    let outcome = unsafe { libc::kill(pid as i32, signal) };
    if outcome == 0 {
        return Ok(());
    }

    let error = std::io::Error::last_os_error();
    if error.raw_os_error() == Some(libc::ESRCH) {
        return Ok(());
    }

    Err(error).with_context(|| format!("Failed to kill process {pid}"))
}

View on GitHub (pinned to 8321021c54)