Hmbown/CodeWhale · error
failed to read bounded stdio JSON-RPC frame
Error message
failed to read bounded stdio JSON-RPC frame: {} What it means
The stdio transport failed while reading a JSON-RPC frame from the child process's stdout under the bounded read (size limit). The frame was invalid (I/O or format error), an error response was sent to the caller, and this error is raised.
Solutions
- Inspect the wrapped source error ({err}) to distinguish size-limit vs I/O failure
- Check the child's stdout for oversized or non-JSON-RPC output
- Verify the configured server command actually speaks newline-delimited JSON-RPC MCP
Example fix
null
Defensive patterns
Strategy: try-catch
Try / catch
match manager.call_tool(...) { Err(e) if e.to_string().starts_with("failed to read bounded stdio JSON-RPC frame") => /* restart child / check stdout */, other => other } Prevention
- Keep child stdout exclusively for JSON-RPC frames (log to stderr)
- Enforce payload size limits in child responses
- Validate the server command produces MCP protocol output
When it happens
Trigger: Child process writes a line exceeding the bounded frame size limit; stdout pipe I/O error; child crashes mid-write producing a truncated/partial line; child emits binary garbage instead of newline-delimited JSON-RPC.
Common situations: MCP server binary printing large debug output or huge payloads; wrong binary/path so a non-MCP program writes to stdout; resource limits causing pipe failures.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
Related errors
- failed to read bounded stdio JSON-RPC frame
- Stdio transport closed
- Stdio transport read error
- child returned a malformed MCP CallToolResult
- child stdout was not valid UTF-8
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/4deec07f8b593578.
Report an issue: GitHub.
Appendix: source
Thrown at crates/mcp/src/lib.rs:906
let mut stdout = io::stdout();
let mut stderr = io::stderr();
let mut state = build_stdio_state(initial_definitions);
let mut input = stdin.lock();
loop {
let line =
match stdio_client::read_bounded_line(&mut input, stdio_client::MAX_JSONRPC_LINE_BYTES)
{
Ok(Some(line)) => line,
Ok(None) => break,
Err(err) => {
let response = jsonrpc_error(
None,
JsonRpcError::parse_error(format!("invalid JSON-RPC frame: {err}")),
);
writeln!(stdout, "{response}")?;
stdout.flush()?;
bail!("failed to read bounded stdio JSON-RPC frame: {err}");
}
};
if line.trim().is_empty() {
continue;
}
let value: Value = match serde_json::from_str(&line) {
Ok(value) => value,
Err(err) => {
let msg = jsonrpc_error(
None,
JsonRpcError::parse_error(format!("invalid json: {err}")),
);
writeln!(stdout, "{msg}")?;
stdout.flush()?;
continue;
}
};View on GitHub (pinned to 433685b202)