{"record":{"id":"dea244f5ae5b6862","repo":"ultraworkers/claw-code","slug":"missing-content-length-header","errorCode":null,"errorMessage":"missing Content-Length header","messagePattern":"missing Content-Length header","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"rust/crates/runtime/src/mcp_server.rs","lineNumber":281,"sourceCode":"        }\n        first_header = false;\n        if line == \"\\r\\n\" || line == \"\\n\" {\n            break;\n        }\n        let header = line.trim_end_matches(['\\r', '\\n']);\n        if let Some((name, value)) = header.split_once(':') {\n            if name.trim().eq_ignore_ascii_case(\"Content-Length\") {\n                let parsed = value\n                    .trim()\n                    .parse::<usize>()\n                    .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;\n                content_length = Some(parsed);\n            }\n        }\n    }\n\n    let content_length = content_length.ok_or_else(|| {\n        io::Error::new(io::ErrorKind::InvalidData, \"missing Content-Length header\")\n    })?;\n    let mut payload = vec![0_u8; content_length];\n    reader.read_exact(&mut payload).await?;\n    Ok(Some(payload))\n}\n\nasync fn write_response(\n    stdout: &mut Stdout,\n    response: &JsonRpcResponse<JsonValue>,\n) -> io::Result<()> {\n    let body = serde_json::to_vec(response)\n        .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;\n    let header = format!(\"Content-Length: {}\\r\\n\\r\\n\", body.len());\n    stdout.write_all(header.as_bytes()).await?;\n    stdout.write_all(&body).await?;\n    stdout.flush().await\n}\n","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/ultraworkers/claw-code/blob/08106b0c3771ef5b4a5aa176acccd460e88b7325/rust/crates/runtime/src/mcp_server.rs#L263-L299","documentation":"Server-side `read_frame` (runtime/src/mcp_server.rs:281): the header block terminated with a blank line (`\\r\\n` or `\\n` both accepted here) but no header named Content-Length (matched case-insensitively after trimming) was parsed. Header lines without a `:` separator are silently ignored, so a misspelled or absent Content-Length lands here. `ErrorKind::InvalidData`.","triggerScenarios":"A client sending only `Content-Type: application/vscode-jsonrpc; charset=utf-8\\r\\n\\r\\n` with no length; `Content_length` misspelling (split at ':' works but the name match fails, so it is ignored); a hand-rolled client that sends the JSON body inline where headers should be and a stray blank line follows.","commonSituations":"Writing a custom MCP client and assuming newline-delimited JSON or that Content-Length is optional; adapting an HTTP client that sends Content-Type first and forgets the length; proxy middleware stripping the header.","solutions":["Fix the client to emit LSP-style framing: `Content-Length: <byte-len>\\r\\n\\r\\n<body>` with the exact byte length of the UTF-8 body.","Test the client against a reference MCP peer to confirm framing before pointing it at claw.","If you control a proxy in between, make sure it forwards the Content-Length header unmodified."],"exampleFix":"# before (client writes headers without length)\nprintf 'Content-Type: application/json\\r\\n\\r\\n{\"jsonrpc\":\"2.0\"}' | claw mcp-serve\n\n# after\nBODY='{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\"}'\nprintf 'Content-Length: %d\\r\\n\\r\\n%s' \"${#BODY}\" \"$BODY\" | claw mcp-serve","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match read_frame(&mut reader).await {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData\n        && e.to_string().contains(\"missing Content-Length\") => {\n        // protocol violation by the peer: close the connection, log the offending client\n    }\n    other => other,\n}","preventionTips":["Emit strict `Content-Length: <len>\\r\\n\\r\\n<body>` framing, length = UTF-8 byte count","Header name match is case-insensitive but must be exactly 'Content-Length' — no underscores","Validate your client against a reference MCP server before pointing it at claw"],"tags":["mcp","stdio","framing","content-length"],"backgroundTag":"missing-content-length-header","analyzedSha":"08106b0c3771ef5b4a5aa176acccd460e88b7325","analyzedAt":"2026-08-18T00:29:38.590Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}