From 7aeb7bc48224a4d6b46e0fa078b86a950fe35713 Mon Sep 17 00:00:00 2001 From: kurushimee Date: Fri, 1 May 2026 20:51:51 +0700 Subject: [PATCH] fix(lsp): omit optional Content-Type header from outgoing messages Per the LSP spec, Content-Type is optional and defaults to application/vscode-jsonrpc; charset=utf-8 (the exact value we were sending). Spec-compliant servers behave identically with or without it. In practice some servers have stricter parsers. Notably, Godot's GDScript LSP (LSPeer::handle_data in modules/gdscript/language_server/gdscript_language_protocol.cpp) extracts the body length via header.substr(16).to_int() and silently drops messages that contain any header beyond Content-Length. Sending only Content-Length is interoperable across the spec-compliant servers we use today and unblocks Godot's LSP. Also tightens the type signature of create_message from tuple[bytes, bytes, bytes] to tuple[bytes, bytes] now that there is no Content-Type element. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/solidlsp/lsp_protocol_handler/server.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/solidlsp/lsp_protocol_handler/server.py b/src/solidlsp/lsp_protocol_handler/server.py index 36e24b15..da94e1eb 100644 --- a/src/solidlsp/lsp_protocol_handler/server.py +++ b/src/solidlsp/lsp_protocol_handler/server.py @@ -131,11 +131,14 @@ class StopLoopException(Exception): pass -def create_message(payload: PayloadLike) -> tuple[bytes, bytes, bytes]: +def create_message(payload: PayloadLike) -> tuple[bytes, bytes]: body = json.dumps(payload, check_circular=False, ensure_ascii=False, separators=(",", ":")).encode(ENCODING) + # NOTE: only Content-Length is sent. Content-Type is optional per the LSP + # spec (default: application/vscode-jsonrpc; charset=utf-8), and Godot's + # GDScript LSP parser only handles Content-Length — any additional header + # makes it silently drop the message. return ( - f"Content-Length: {len(body)}\r\n".encode(ENCODING), - "Content-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n".encode(ENCODING), + f"Content-Length: {len(body)}\r\n\r\n".encode(ENCODING), body, )