NousResearch/hermes-agent · error · LSPProtocolError

non-integer Content-Length: {cl!r}

Error message

non-integer Content-Length: {cl!r}

What it means

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.

Source

Thrown at agent/lsp/protocol.py:113

            )
        line = line[:-2]  # strip CRLF
        if not line:
            break  # blank line ends header block
        try:
            key, _, value = line.decode("ascii").partition(":")
        except UnicodeDecodeError as e:
            raise LSPProtocolError(f"non-ASCII LSP header: {line!r}") from e
        if not key:
            raise LSPProtocolError(f"malformed LSP header line: {line!r}")
        headers[key.strip().lower()] = value.strip()

    cl = headers.get("content-length")
    if cl is None:
        raise LSPProtocolError(f"LSP message missing Content-Length: {headers!r}")
    try:
        n = int(cl)
    except ValueError as e:
        raise LSPProtocolError(f"non-integer Content-Length: {cl!r}") from e
    if n < 0 or n > 64 * 1024 * 1024:  # 64 MiB sanity cap
        raise LSPProtocolError(f"unreasonable Content-Length: {n}")

    try:
        body = await reader.readexactly(n)
    except asyncio.IncompleteReadError as e:
        raise LSPProtocolError(
            f"truncated LSP body: expected {n} bytes, got {len(e.partial)}"
        ) from e

    try:
        return json.loads(body.decode("utf-8"))
    except json.JSONDecodeError as e:
        raise LSPProtocolError(f"invalid JSON in LSP body: {e}") from e
    except UnicodeDecodeError as e:
        raise LSPProtocolError(f"non-UTF-8 LSP body: {e}") from e

View on GitHub (pinned to c896c09c42)

Solutions

  1. Upgrade/patch the server — a non-integer Content-Length is always a server-side framing bug.
  2. Remove any proxy/wrapper between client and server that could rewrite the stream.
  3. Capture the raw stream (tee shim) to confirm the exact malformed value and report it upstream.
Defensive patterns

Strategy: fallback

Validate before calling

# server-side guard: assert the length is a plain int before writing
def safe_content_length(body: bytes) -> str:
    n = len(body)
    assert isinstance(n, int) and n >= 0
    return str(n)  # str(int) never emits separators or hex

Try / catch

try:
    msg = await read_message(reader)
except LSPProtocolError as e:
    if "non-integer Content-Length" in str(e):
        restart_session()  # corrupt framing; a fresh process pair is the only recovery
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: Servers computing Content-Length with locale-dependent formatting (thousands separators); response corruption through a non-transparent proxy; hand-rolled framing bugs.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/73a04e97fc166340. Report an issue: GitHub.