{"record":{"id":"8fb34e15ce1e4f59","repo":"Hmbown/CodeWhale","slug":"failed-to-wait-for-gh-api-e","errorCode":null,"errorMessage":"Failed to wait for `gh api`: {e}","messagePattern":"Failed to wait for `gh api`: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/lib.rs","lineNumber":9738,"sourceCode":"        .arg(format!(\"repos/{repo}/pulls/{number}/reviews\"))\n        .arg(\"--input\")\n        .arg(\"-\")\n        .stdin(std::process::Stdio::piped())\n        .stdout(std::process::Stdio::piped())\n        .stderr(std::process::Stdio::piped());\n    let mut child = cmd\n        .spawn()\n        .map_err(|e| anyhow::anyhow!(\"Failed to run `gh api`: {e}\"))?;\n    *publication = ReviewPublication::Uncertain;\n    if let Some(stdin) = child.stdin.as_mut() {\n        use std::io::Write;\n        stdin\n            .write_all(serde_json::to_string(&payload)?.as_bytes())\n            .map_err(|e| anyhow::anyhow!(\"Failed to write review payload: {e}\"))?;\n    }\n    let output = child\n        .wait_with_output()\n        .map_err(|e| anyhow::anyhow!(\"Failed to wait for `gh api`: {e}\"))?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();\n        bail!(\"gh api POST repos/{repo}/pulls/{number}/reviews failed: {stderr}\");\n    }\n    *publication = ReviewPublication::Posted;\n    Ok(())\n}\n\n/// Publish a completed PR review exactly once: resolve the repository, render\n/// the summary, and include every comment whose position the diff confirms.\n/// A failed request can have an uncertain remote outcome, so reconciliation\n/// and any retry stay under the caller's control rather than risking a duplicate.\nfn post_pr_review(\n    number: u32,\n    view: &GhPullRequest,\n    repo: Option<&str>,\n    review: &crate::tools::review::ReviewOutput,\n    diff: &str,","sourceCodeStart":9720,"sourceCodeEnd":9756,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/lib.rs#L9720-L9756","documentation":"Raised when the code fails to reap the spawned `gh api` child process via `wait_with_output()` while posting a PR review. This is an OS-level I/O failure around the child process (spawn/pipe/read), not a GitHub HTTP error — HTTP-level failures are surfaced separately via the stderr bail right after. The review post is aborted with an uncertain publication state.","triggerScenarios":"`child.wait_with_output()` returns Err while waiting for the `gh api POST repos/{repo}/pulls/{number}/reviews` process — e.g. the process was reaped elsewhere first, the runtime could not read its stdout/stderr pipes, or the process was killed in a way that makes wait fail.","commonSituations":"Process reapers/monitors that double-reap children; resource exhaustion (fork failures, fd limits) under load; container runtimes with unusual process semantics; intermittent OS-level I/O errors.","solutions":["Retry the review-post operation; this is usually a transient OS-level failure","Check system resource limits (ulimit -n for fd exhaustion) and raise if processes/fds are leaking","Ensure no other code path in the app reaps the same child (would cause wait to fail)","If persistent, capture `gh api` output via a temp file instead of pipes to sidestep pipe-read failures"],"exampleFix":"// before\nlet output = child.wait_with_output()\n    .map_err(|e| anyhow::anyhow!(\"Failed to wait for `gh api`: {e}\"))?;\n// after\nlet output = match child.wait_with_output() {\n    Ok(o) => o,\n    Err(e) => { tracing::warn!(\"gh api wait failed: {e}; retrying once\"); child2.wait_with_output()? }\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust\nlet output = child.wait_with_output()\n    .map_err(|e| anyhow::anyhow!(\"Failed to wait for `gh api`: {e}\"))\n    .with_context(|| format!(\"waiting for gh api on {repo}#{number}\"))?;\nif !output.status.success() {\n    let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();\n    bail!(\"gh api failed: {stderr}\");\n}","preventionTips":["Do not double-reap child processes elsewhere in the app","Keep fd/process limits healthy in CI containers","Retry once on transient wait failures before surfacing to the user","Log the repo/PR context so failed reviews can be re-posted safely"],"tags":["process","github-cli","process-management"],"backgroundTag":"http-request-failed","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"}