{"record":{"id":"7edef7522177c75c","repo":"Hmbown/CodeWhale","slug":"stderr-unavailable","errorCode":null,"errorMessage":"stderr unavailable","messagePattern":"stderr unavailable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":10561,"sourceCode":"\n    let mut cmd = Command::new(exec_env.program());\n    cmd.args(exec_env.args())\n        .current_dir(&exec_env.cwd)\n        .stdout(Stdio::piped())\n        .stderr(Stdio::piped());\n    child_env::apply_to_command(&mut cmd, child_env::string_map_env(&exec_env.env));\n\n    let mut child = cmd\n        .spawn()\n        .map_err(|e| anyhow::anyhow!(\"Failed to run command: {e}\"))?;\n    let stdout_handle = child\n        .stdout\n        .take()\n        .ok_or_else(|| anyhow::anyhow!(\"stdout unavailable\"))?;\n    let stderr_handle = child\n        .stderr\n        .take()\n        .ok_or_else(|| anyhow::anyhow!(\"stderr unavailable\"))?;\n\n    let timeout = exec_env.timeout;\n    let stdout_thread = std::thread::spawn(move || {\n        let mut reader = stdout_handle;\n        let mut buf = Vec::new();\n        let _ = reader.read_to_end(&mut buf);\n        buf\n    });\n    let stderr_thread = std::thread::spawn(move || {\n        let mut reader = stderr_handle;\n        let mut buf = Vec::new();\n        let _ = reader.read_to_end(&mut buf);\n        buf\n    });\n\n    if let Some(status) = child.wait_timeout(timeout)? {\n        let stdout = stdout_thread.join().unwrap_or_default();\n        let stderr = stderr_thread.join().unwrap_or_default();","sourceCodeStart":10543,"sourceCodeEnd":10579,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/lib.rs#L10543-L10579","documentation":"Thrown when `child.stderr` is None after spawning. Like the stdout case, this should be impossible while `.stderr(Stdio::piped())` is configured, so it flags a broken invariant or double-take of the pipe.","triggerScenarios":"`child.stderr.take()` returning None because stderr was not configured as piped or was already consumed.","commonSituations":"Someone removed the `.stderr(Stdio::piped())` configuration; stderr taken twice; merging stderr into stdout while still trying to take it separately.","solutions":["Verify `.stderr(Stdio::piped())` is set on the Command before spawn","Take stderr exactly once per child","If stderr is merged via Stdio::piped into stdout, remove the separate take"],"exampleFix":"// before\n.stderr(Stdio::inherit()); // then child.stderr.take() -> None\n// after\n.stderr(Stdio::piped());","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let stderr = child.stderr.take()\n    .ok_or_else(|| anyhow::anyhow!(\"stderr unavailable: stderr was not piped before spawn\"))?;","preventionTips":["Keep .stderr(Stdio::piped()) adjacent to the stderr take","Do not merge stderr into stdout if stderr is consumed separately","Take each pipe exactly once"],"tags":["process","stderr","pipe"],"backgroundTag":"internal-invariant-violation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}