{"record":{"id":"3ce88148d15d2127","repo":"openai/codex","slug":"invaliddata-3ce881","errorCode":"InvalidData","errorMessage":"oversized MCP SSE event was already rejected","messagePattern":"oversized MCP SSE event was already rejected","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"codex-rs/rmcp-client/src/http_client_adapter.rs","lineNumber":999,"sourceCode":"    previous_was_carriage_return: bool,\n    failed: bool,\n}\n\nimpl SseEventSizeLimit {\n    fn new(maximum_bytes: Option<usize>) -> Self {\n        Self {\n            maximum_bytes,\n            retained_bytes: 0,\n            line_bytes: 0,\n            line_is_comment: false,\n            previous_was_carriage_return: false,\n            failed: false,\n        }\n    }\n\n    fn observe(&mut self, bytes: &[u8]) -> io::Result<()> {\n        if self.failed {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"oversized MCP SSE event was already rejected\",\n            ));\n        }\n        let Some(maximum_bytes) = self.maximum_bytes else {\n            return Ok(());\n        };\n\n        for &byte in bytes {\n            if self.previous_was_carriage_return {\n                self.previous_was_carriage_return = false;\n                if byte == b'\\n' {\n                    continue;\n                }\n            }\n\n            match byte {\n                b'\\r' => {","sourceCodeStart":981,"sourceCodeEnd":1017,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/rmcp-client/src/http_client_adapter.rs#L981-L1017","documentation":"SseEventSizeLimit::observe() is sticky: once an SSE event breached the per-event size limit, the failed flag stays set and every subsequent body chunk observation returns this InvalidData error. It exists so the byte stream built in sse_stream_from_body keeps erroring instead of silently resuming mid-event after the real failure. Seeing it means the stream already produced the primary 'MCP response body exceeds N bytes' error earlier.","triggerScenarios":"Any bytes arriving on the HTTP body stream after an earlier check_limit() failure — e.g. the caller keeps polling the SSE stream after the first oversize error and the server keeps sending the remainder of the huge event.","commonSituations":"Drain loops that log every SSE item and show a cascade of these errors; retry logic polling a dead stream; reading logs where the first real error scrolled past and only these remain visible.","solutions":["Treat any error from the SSE stream as terminal: stop polling, drop the connection, reconnect","Find the first 'MCP response body exceeds N bytes' error earlier in the same stream/log — that is the root cause","Fix the server so no single event exceeds the limit","If you aggregate errors, deduplicate consecutive stream errors to avoid alarm noise"],"exampleFix":"// before\nwhile let Some(item) = event_stream.next().await { /* logs a cascade of 'already rejected' */ }\n\n// after\nwhile let Some(item) = event_stream.next().await {\n    if item.is_err() { break; } // first error is fatal; reconnect\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_already_rejected(error: &std::io::Error) -> bool {\n    error.kind() == std::io::ErrorKind::InvalidData\n        && error.to_string().contains(\"already rejected\")\n}","tryCatchPattern":"// sticky failure: first error (any error) is terminal for the stream\nwhile let Some(item) = event_stream.next().await {\n    let item = match item {\n        Ok(item) => item,\n        Err(error) => {\n            warn!(\"SSE stream failed ({error}); dropping connection\");\n            break; // reconnect rather than keep polling\n        }\n    };\n}","preventionTips":["Treat every SSE stream error as fatal to that connection","When debugging, scroll to the FIRST size error — 'already rejected' is only an echo","Deduplicate consecutive stream errors in log aggregation"],"tags":["rust","mcp","sse","size-limit","sticky-error"],"backgroundTag":"sse-event-size-limit","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}