affaan-m/ECC · error
ECC runner did not expose a process id
Error message
ECC runner did not expose a process id
What it means
After spawning the ECC runner child process, the code reads child.id(); on some platforms/spawn failure modes std returns None even though spawn() reported success. The manager treats an unknown pid as fatal because session stop/monitoring depends on it.
Solutions
- Retry the spawn once; transient races usually resolve
- Check that the runner executable at current_exe-relative path exists and is not blocked by AV/EDR
- Log the OS-level spawn error and fall back to running the runner synchronously if pid tracking is not required
Example fix
// before
child.id().ok_or_else(|| anyhow::anyhow!("ECC runner did not expose a process id"))?;
// after
let pid = child.id().with_context(|| format!("ECC runner exited before pid could be read (status: {:?})", child.try_wait()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// no pre-call check possible for child.id(); verify executable first
assert!(current_exe.join("runner").exists(), "runner binary missing"); Try / catch
match spawn_runner().await {
Ok(pid) => track(pid),
Err(e) if e.to_string().contains("did not expose a process id") => {
eprintln!("runner exited before pid capture; check runner logs");
}
Err(e) => return Err(e),
} Prevention
- Ensure the runner binary is present and not blocked by AV/EDR
- Test spawns on the target OS (Windows quirks)
- Detect instant child exit via try_wait and report its status
When it happens
Trigger: command.spawn() succeeds but the Child handle reports no pid — typically on Windows where pid exposure can fail, or when the process exits/reaps extremely quickly between spawn and id().
Common situations: Windows targets with restricted process handles; antivirus/EDR intercepting the spawned binary; spawning a binary path that dies instantly.
Related errors
- Claude Code did not expose a process id
- Spawned process did not expose a process id
- Codex probe failed
- failed
- git add failed for
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/f0b8cdcdf6576eba.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/manager.rs:3027
.arg(session_id)
.arg("--task")
.arg(task)
.arg("--agent")
.arg(agent_type)
.arg("--cwd")
.arg(working_dir)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::from(stderr_log));
configure_background_runner_command(&mut command);
let child = command
.spawn()
.with_context(|| format!("Failed to spawn ECC runner from {}", current_exe.display()))?;
child
.id()
.ok_or_else(|| anyhow::anyhow!("ECC runner did not expose a process id"))?;
Ok(())
}
fn background_runner_stderr_log_path(working_dir: &Path, session_id: &str) -> PathBuf {
working_dir
.join(".claude")
.join("ecc2")
.join("logs")
.join(format!("{session_id}.runner-stderr.log"))
}
#[cfg(windows)]
fn detached_creation_flags() -> u32 {
const DETACHED_PROCESS: u32 = 0x0000_0008;
const CREATE_NEW_PROCESS_GROUP: u32 = 0x0000_0200;
DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
}
View on GitHub (pinned to 8321021c54)