NousResearch/hermes-agent · error · LSPProtocolError
truncated LSP body: expected {n} bytes, got {len(e.partial)}
Error message
truncated LSP body: expected {n} bytes, got {len(e.partial)} What it means
LSPProtocolError raised when readexactly(n) — reading the Content-Length-declared body — hits EOF after only len(e.partial) bytes. The server promised n bytes but died or closed stdout before delivering them, so the JSON body is incomplete and cannot be parsed.
Source
Thrown at agent/lsp/protocol.py:120
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
def make_request(req_id: int, method: str, params: Any) -> dict:
"""Build a JSON-RPC 2.0 request envelope."""
msg: dict = {"jsonrpc": "2.0", "id": req_id, "method": method}
if params is not None:
msg["params"] = params
return msg
View on GitHub (pinned to c896c09c42)
Solutions
- Restart the client and server, then re-open documents to retrigger the work — a mid-body death is a server crash, and stderr (drained at debug level) usually names the exception.
- Raise memory/ulimits for the server process if it dies on large payloads.
- If one specific file reliably kills the server, exclude it or update the server — report the crash upstream.
Defensive patterns
Strategy: retry
Try / catch
try:
msg = await read_message(reader)
except LSPProtocolError as e:
if "truncated LSP body" in str(e):
client = await restart_client_and_reopen_docs(client) # server died mid-write
msg = await read_message(reader)
else:
raise Prevention
- Raise memory limits for native servers (clangd, rust-analyzer) on large workspaces — OOM mid-response is the usual cause.
- Watch server exit codes; a truncated body is always a dead server, and stderr holds why.
- Build restart-and-replay into long-running LSP sessions so one crash does not kill the editor integration.
When it happens
Trigger: Server killed (OOM, signal) mid-write of a large response; server crashing while serializing a huge diagnostics payload; process exiting abruptly after sending headers (e.g. unhandled exception after write of headers but before body flush).
Common situations: Memory limits on containers running clangd/rust-analyzer with big workspaces; servers crashing on specific pathological files; forced shutdowns during heavy indexing.
Related errors
- unexpected EOF while reading LSP headers (partial={e.partial
- LSP server binary not found: {cmd[0]} ({e})
- cannot send {method!r}: stdin closed
- send failed for {method!r}: {e}
- LSP header block exceeded 8 KiB without terminator
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/c4c5c669c356500c.
Report an issue: GitHub.