{"record":{"id":"73a04e97fc166340","repo":"NousResearch/hermes-agent","slug":"non-integer-content-length-cl-r","errorCode":null,"errorMessage":"non-integer Content-Length: {cl!r}","messagePattern":"non-integer Content-Length: (.+?)","errorType":"exception","errorClass":"LSPProtocolError","httpStatus":null,"severity":"error","filePath":"agent/lsp/protocol.py","lineNumber":113,"sourceCode":"            )\n        line = line[:-2]  # strip CRLF\n        if not line:\n            break  # blank line ends header block\n        try:\n            key, _, value = line.decode(\"ascii\").partition(\":\")\n        except UnicodeDecodeError as e:\n            raise LSPProtocolError(f\"non-ASCII LSP header: {line!r}\") from e\n        if not key:\n            raise LSPProtocolError(f\"malformed LSP header line: {line!r}\")\n        headers[key.strip().lower()] = value.strip()\n\n    cl = headers.get(\"content-length\")\n    if cl is None:\n        raise LSPProtocolError(f\"LSP message missing Content-Length: {headers!r}\")\n    try:\n        n = int(cl)\n    except ValueError as e:\n        raise LSPProtocolError(f\"non-integer Content-Length: {cl!r}\") from e\n    if n < 0 or n > 64 * 1024 * 1024:  # 64 MiB sanity cap\n        raise LSPProtocolError(f\"unreasonable Content-Length: {n}\")\n\n    try:\n        body = await reader.readexactly(n)\n    except asyncio.IncompleteReadError as e:\n        raise LSPProtocolError(\n            f\"truncated LSP body: expected {n} bytes, got {len(e.partial)}\"\n        ) from e\n\n    try:\n        return json.loads(body.decode(\"utf-8\"))\n    except json.JSONDecodeError as e:\n        raise LSPProtocolError(f\"invalid JSON in LSP body: {e}\") from e\n    except UnicodeDecodeError as e:\n        raise LSPProtocolError(f\"non-UTF-8 LSP body: {e}\") from e\n\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/lsp/protocol.py#L95-L131","documentation":"LSPProtocolError raised when a Content-Length header exists but int() cannot parse its value — e.g. 'Content-Length: 12 5', '0x40', or empty. The header block parsed structurally, yet the one value the framer needs is not a decimal integer.","triggerScenarios":"Malformed or corrupted Content-Length values from a buggy server; value containing whitespace in the middle or a trailing non-numeric character; framing desync reinterpreting body bytes as a header value.","commonSituations":"Servers computing Content-Length with locale-dependent formatting (thousands separators); response corruption through a non-transparent proxy; hand-rolled framing bugs.","solutions":["Upgrade/patch the server — a non-integer Content-Length is always a server-side framing bug.","Remove any proxy/wrapper between client and server that could rewrite the stream.","Capture the raw stream (tee shim) to confirm the exact malformed value and report it upstream."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"# server-side guard: assert the length is a plain int before writing\ndef safe_content_length(body: bytes) -> str:\n    n = len(body)\n    assert isinstance(n, int) and n >= 0\n    return str(n)  # str(int) never emits separators or hex","typeGuard":null,"tryCatchPattern":"try:\n    msg = await read_message(reader)\nexcept LSPProtocolError as e:\n    if \"non-integer Content-Length\" in str(e):\n        restart_session()  # corrupt framing; a fresh process pair is the only recovery\n    else:\n        raise","preventionTips":["Compute Content-Length from the encoded byte string, formatted via str(int).","Avoid locale-sensitive number formatting anywhere near the wire.","Remove stream-rewriting proxies between client and server."],"tags":["lsp","protocol","framing"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}