{"record":{"id":"31a37bebcd4ff6db","repo":"Hmbown/CodeWhale","slug":"mcp-stdio-line-exceeded-max-bytes","errorCode":null,"errorMessage":"MCP stdio line exceeded {max} bytes","messagePattern":"MCP stdio line exceeded (.+?) bytes","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/stdio.rs","lineNumber":434,"sourceCode":"{\n    use tokio::io::AsyncBufReadExt;\n    loop {\n        let (chunk, consumed, done) = {\n            let available = reader.fill_buf().await?;\n            if available.is_empty() {\n                (Vec::new(), 0usize, true)\n            } else if let Some(pos) = available.iter().position(|&b| b == b'\\n') {\n                (available[..=pos].to_vec(), pos + 1, true)\n            } else {\n                (available.to_vec(), available.len(), false)\n            }\n        };\n        if consumed > 0 {\n            reader.consume(consumed);\n        }\n        out.extend_from_slice(&chunk);\n        if out.len() > max {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                format!(\"MCP stdio line exceeded {max} bytes\"),\n            ));\n        }\n        if done {\n            break;\n        }\n    }\n    Ok(out.len())\n}\n\n#[cfg(test)]\nmod read_cap_tests {\n    use super::read_line_capped;\n\n    #[tokio::test]\n    async fn cancelled_partial_read_preserves_next_frame() {\n        use futures_util::FutureExt;","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/stdio.rs#L416-L452","documentation":"read_line_capped enforces a per-line byte cap on the MCP stdio transport. As it accumulates bytes it errors with InvalidData once the buffered line exceeds max, preventing a misbehaving or malicious server from exhausting memory with an unterminated line.","triggerScenarios":"recv (or the tests cancelled_partial_read_preserves_next_frame / aborts_on_newline_free_line_over_cap) reads a line from the MCP stdio server whose length surpasses the configured max before a newline arrives.","commonSituations":"A server emitting huge JSON-RPC frames on a single line; a broken server writing binary/noise without newlines; a misconfigured max line size that is smaller than legitimate responses.","solutions":["Fix or update the MCP server so it emits frames within the size cap.","Raise the transport's max line size if your server legitimately sends very large responses.","Inspect server stderr/logs for corrupted output causing unbounded lines."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match recv().await {\n    Err(e) if e.to_string().contains(\"line exceeded\") => {\n        eprintln!(\"server sent an oversized frame; restart server or raise max\");\n        restart_server_and_retry().await\n    }\n    other => other,\n}","preventionTips":["Keep MCP server responses within the transport's line cap; paginate large results.","Configure a max line size comfortably above your server's largest legitimate frame.","Treat unbounded output from a server as a server bug to fix."],"tags":["mcp","stdio","limit","protocol"],"backgroundTag":"payload-too-large","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}