tinyhumansai/openhuman · error · anyhow::Error
claude child stdout missing
Error message
claude child stdout missing
What it means
Taking the piped stdout handle from the spawned claude child returned None. Unreachable in normal operation because Stdio::piped was requested at spawn; hitting it means the stdio configuration was lost or the handle already taken — a type-guard failure on the Option, not an IO error.
Source
Thrown at src/openhuman/inference/provider/claude_code/driver.rs:406
let mut child = cmd
.spawn()
.map_err(|e| anyhow::anyhow!("failed to spawn `claude`: {e}"))?;
if let Some(mut stdin) = child.stdin.take() {
stdin
.write_all(&stdin_bytes)
.await
.map_err(|e| anyhow::anyhow!("write stdin: {e}"))?;
stdin
.shutdown()
.await
.map_err(|e| anyhow::anyhow!("close stdin: {e}"))?;
}
let mut stdout = child
.stdout
.take()
.ok_or_else(|| anyhow::anyhow!("claude child stdout missing"))?;
let mut stderr = child
.stderr
.take()
.ok_or_else(|| anyhow::anyhow!("claude child stderr missing"))?;
let mut parser = StreamJsonParser::new();
let mut mapper = EventMapper::new();
let mut buf = [0u8; 8192];
// Drain stderr in parallel into a buffer for diagnostics.
let stderr_task = tokio::spawn(async move {
let mut acc = String::new();
let mut tmp = [0u8; 4096];
while let Ok(n) = stderr.read(&mut tmp).await {
if n == 0 {
break;
}
acc.push_str(&String::from_utf8_lossy(&tmp[..n]));View on GitHub (pinned to 7491200858)
Solutions
- Ensure stdout is configured as Stdio::piped when spawning
- Audit for any code taking the handle before the driver
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at src/openhuman/inference/provider/claude_code/driver.rs:406 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/31021be4124e4f09.
Report an issue: GitHub.