Hmbown/CodeWhale · error
lane child stderr was not piped
Error message
lane child stderr was not piped
What it means
The sibling guard for stderr in run_lane_log_proxy: after spawning the lane child with .stderr(Stdio::piped()), child.stderr.take() returned None, so the proxy cannot stream the child's stderr into the lane log. It appends a lane_proxy_failure event and publishes exit receipt 125. Like the stdout variant it is an internal invariant guard that should be unreachable with the current spawn configuration.
Solutions
- Confirm .stderr(Stdio::piped()) is still chained before child_command.spawn() at crates/lane/src/runtime.rs:469
- If the Command is assembled in another function, keep the piped-stdio configuration at the spawn site and assert it
- Add/keep a regression test that exercises run_lane_log_proxy end-to-end so any stdio change is caught
- Read the lane log's lane_proxy_error entry to confirm the 125 exit path
Example fix
// before child_command.stdout(Stdio::piped()); let mut child = child_command.spawn()?; // after child_command.stdout(Stdio::piped()).stderr(Stdio::piped()); let mut child = child_command.spawn()?;
Defensive patterns
Strategy: validation
Validate before calling
let mut cmd = Command::new(&command[0]);
cmd.args(&command[1..]).stdout(Stdio::piped()).stderr(Stdio::piped());
let mut child = cmd.spawn().context("spawn lane child")?;
debug_assert!(child.stderr.is_some()); Type guard
fn piped_stderr(child: &Child) -> Option<&ChildStderr> { child.stderr.as_ref() } Try / catch
let stderr = match child.stderr.take() {
Some(s) => s,
None => return fail(anyhow!("lane child stderr was not piped"), 125),
}; Prevention
- Chain .stdout(Stdio::piped()).stderr(Stdio::piped()) immediately before spawn
- Never let the Child pass through code that resets stdio to inherit/null
- Cover the proxy path with a round-trip test that asserts both streams reach the lane log
When it happens
Trigger: The .stderr(Stdio::piped()) configuration is missing or removed before spawn; the Child was constructed by code that configured stderr as inherit/null; a platform quirk yields a successful spawn without a stderr pipe.
Common situations: Refactors that split child-command construction; helpers that return a Child rebuilt without stderr piped; downstream merges that touch the spawn block at runtime.rs:466-478.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- lane child stdout was not piped
- 125
- connection stdin poisoned by an earlier panic
- event recovery buffer fits u64
- event transaction runs once
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/7962137ed6aec587.
Report an issue: GitHub.
Appendix: source
Thrown at crates/lane/src/runtime.rs:485
child_command.args(&command[1..]);
child_command.envs(environment);
child_command.stdout(Stdio::piped()).stderr(Stdio::piped());
let mut child = match child_command.spawn() {
Ok(child) => child,
Err(error) => {
return fail(
anyhow::Error::from(error).context(format!("spawn lane child command {command:?}")),
127,
);
}
};
let stdout = match child.stdout.take() {
Some(stdout) => stdout,
None => return fail(anyhow::anyhow!("lane child stdout was not piped"), 125),
};
let stderr = match child.stderr.take() {
Some(stderr) => stderr,
None => return fail(anyhow::anyhow!("lane child stderr was not piped"), 125),
};
let stdout_log = log_path.clone();
let stderr_log = log_path.clone();
let stdout_thread = thread::spawn(move || stream_child_output(stdout, stdout_log, "stdout"));
let stderr_thread = thread::spawn(move || stream_child_output(stderr, stderr_log, "stderr"));
let status = match child.wait() {
Ok(status) => status,
Err(error) => {
return fail(
anyhow::Error::from(error).context(format!("wait for lane child {command:?}")),
LANE_PROXY_FAILURE_EXIT_CODE,
);
}
};
let stdout_result = stdout_thread
.join()
.map_err(|_| anyhow::anyhow!("lane proxy stdout logger panicked"))?;View on GitHub (pinned to 433685b202)