openai/codex · error

MCP HTTP headers helper stdout was unavailable

Error message

MCP HTTP headers helper stdout was unavailable

What it means

run_helper() takes child.stdout to read the JSON output; take() returns None only if stdout was not piped or was already consumed. The command is always built with .stdout(Stdio::piped()), so in practice this error signals a broken internal invariant — the spawn configuration was changed or stdout was taken before the read — rather than anything a user can configure.

Source

Thrown at codex-rs/rmcp-client/src/http_headers.rs:325

    #[cfg(not(windows))]
    let child = process
        .spawn()
        .map_err(|error| anyhow!("MCP HTTP headers helper failed to start: {error}"))?;
    let mut process = HelperProcess {
        #[cfg(unix)]
        process_group_id: child
            .id()
            .ok_or_else(|| anyhow!("MCP HTTP headers helper process id was unavailable"))?,
        child,
        #[cfg(windows)]
        job,
    };
    let output = tokio::time::timeout(HELPER_TIMEOUT, async {
        let stdout = process
            .child
            .stdout
            .take()
            .ok_or_else(|| anyhow!("MCP HTTP headers helper stdout was unavailable"))?;
        let mut output = Vec::new();
        stdout
            .take((MAX_HELPER_OUTPUT_BYTES + 1) as u64)
            .read_to_end(&mut output)
            .await?;
        if output.len() > MAX_HELPER_OUTPUT_BYTES {
            return Err(anyhow!("MCP HTTP headers helper output exceeds 64 KiB"));
        }
        let status = process.child.wait().await?;
        if !status.success() {
            return Err(anyhow!(
                "MCP HTTP headers helper exited with status {status}"
            ));
        }
        Ok(output)
    })
    .await
    .map_err(|_| anyhow!("MCP HTTP headers helper timed out after 10 seconds"))??;

View on GitHub (pinned to 339751715c)

Solutions

  1. Keep Stdio::piped() for helper stdout in the spawn configuration
  2. Do not take() child.stdout before the read future runs
  3. If seen with a stock build, report it as an internal bug upstream
Defensive patterns

Strategy: try-catch

Type guard

fn is_helper_stdout_unavailable(error: &anyhow::Error) -> bool {
    error.to_string().contains("stdout was unavailable")
}

Try / catch

// internal invariant: report rather than retry
if let Err(error) = provider.headers().await {
    if error.to_string().contains("stdout was unavailable") {
        // stock builds should never hit this; file an upstream bug
    }
}

Prevention

When it happens

Trigger: Internal only: piped stdout missing on the spawned helper because Stdio::piped() was removed or stdout was taken elsewhere before the read task.

Common situations: Only after modifying rmcp-client spawn code or a custom fork; not reachable through normal MCP server configuration.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/6797c34c90249b20. Report an issue: GitHub.