affaan-m/ECC · error
Spawned process did not expose a process id
Error message
Spawned process did not expose a process id
What it means
capture_command_output spawns the session command and immediately needs its pid to record via db_writer.update_pid. child.id() returning None (process already reaped or platform pid exposure failure) aborts capture with this error, since heartbeat/stop tracking is pid-based.
Solutions
- Verify the command runs standalone before scheduling it in a session
- Capture and report child.try_wait() status alongside the missing pid to reveal the instant exit
- Retry the spawn; if pid tracking is optional, degrade gracefully instead of failing the whole capture
Example fix
// before
let pid = child.id().ok_or_else(|| anyhow::anyhow!("Spawned process did not expose a process id"))?;
// after
let pid = child.id().with_context(|| format!("spawned process exited immediately: {:?}", child.try_wait()))?; Defensive patterns
Strategy: try-catch
Validate before calling
// dry-run the command first
let ok = Command::new("sh").arg("-c").arg("command -v <cmd>").status().map(|s| s.success()).unwrap_or(false);
assert!(ok, "command not runnable"); Try / catch
match capture_command_output(...).await {
Err(e) if e.to_string().contains("did not expose a process id") => {
eprintln!("process exited before pid capture; inspect command args and output");
}
Err(e) => return Err(e),
Ok(v) => v,
} Prevention
- Validate command strings/args before scheduling sessions
- Handle instantly-exiting commands (bad binaries, bad env)
- Report try_wait() status when pid capture fails for better diagnostics
When it happens
Trigger: The spawned command exits instantly (bad args, missing interpreter) so the Child has no id; or a platform-level spawn quirk (Windows) prevents pid exposure right after a successful spawn().
Common situations: Command string referencing a nonexistent binary wrapped by a shell that exits immediately; stdin/stderr piping misconfiguration causing early exit; race with very short-lived processes.
Related errors
- Claude Code did not expose a process id
- ECC runner did not expose a process id
- Codex probe failed
- failed
- DB writer acknowledgement dropped
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/1fbd997496e2fbff.
Report an issue: GitHub.
Appendix: source
Thrown at ecc2/src/session/runtime.rs:172
Some(stdout) => stdout,
None => {
let _ = child.kill().await;
let _ = child.wait().await;
anyhow::bail!("Child stdout was not piped");
}
};
let stderr = match child.stderr.take() {
Some(stderr) => stderr,
None => {
let _ = child.kill().await;
let _ = child.wait().await;
anyhow::bail!("Child stderr was not piped");
}
};
let pid = child
.id()
.ok_or_else(|| anyhow::anyhow!("Spawned process did not expose a process id"))?;
db_writer.update_pid(Some(pid)).await?;
db_writer.update_state(SessionState::Running).await?;
db_writer.touch_heartbeat().await?;
let heartbeat_writer = db_writer.clone();
let heartbeat_task = tokio::spawn(async move {
let mut ticker = time::interval(heartbeat_interval);
ticker.set_missed_tick_behavior(MissedTickBehavior::Delay);
loop {
ticker.tick().await;
if heartbeat_writer.touch_heartbeat().await.is_err() {
break;
}
}
});
let stdout_task = tokio::spawn(capture_stream(
session_id.clone(),View on GitHub (pinned to 8321021c54)