microsoft/typescript-go · error · ErrorCode
-32600
-32600
Error message
%w: %w
What it means
In lspReader.Read (server.go:133-137), the raw JSON-RPC message itself failed to unmarshal into lsproto.Message — malformed frame JSON, missing protocol-required members (jsonrpc/method), wrong top-level kinds — and the error does not classify as InvalidParams, so it is wrapped with ErrorCodeInvalidRequest (-32600). Unlike the -32602 path, the message is returned as nil: the frame is unidentifiable and only a generic error response (if the id could be recovered) is possible.
Source
Thrown at internal/lsp/server.go:137
func (e *messageMarshalError) Error() string { return "failed to marshal message: " + e.err.Error() }
func (e *messageMarshalError) Unwrap() []error {
return []error{lsproto.ErrorCodeInternalError, e.err}
}
func (r *lspReader) Read() (*lsproto.Message, error) {
data, err := r.r.Read()
if err != nil {
return nil, err
}
req := &lsproto.Message{}
if err := json.Unmarshal(data, req); err != nil {
if errors.Is(err, lsproto.ErrorCodeInvalidParams) {
return req, fmt.Errorf("%w: %w", lsproto.ErrorCodeInvalidParams, err)
}
return nil, fmt.Errorf("%w: %w", lsproto.ErrorCodeInvalidRequest, err)
}
return req, nil
}
func ToReader(r io.Reader) Reader {
return &lspReader{r: lsproto.NewBaseReader(r)}
}
func (w *lspWriter) Write(msg *lsproto.Message) error {
data, err := json.Marshal(msg)
if err != nil {
return &messageMarshalError{err: err}
}
return w.w.Write(data)
}
func ToWriter(w io.Writer) Writer {View on GitHub (pinned to 1bcfa18d79)
Solutions
- Log the raw frame bytes and validate them with an independent JSON-RPC parser; fix framing (exact Content-Length byte count, UTF-8 no BOM).
- Ensure single messages only — no batch arrays — and that every request/notification carries jsonrpc and method.
- If a specific required member is rejected, compare against the JSON-RPC 2.0 shape lsproto.Message enforces (union of request/notification/response with strict kinds).
- For proxies, pass the byte stream through unmodified and never interleave stdout writes.
Example fix
// before: batch frame
[{"jsonrpc":"2.0","id":1,"method":"shutdown"}]
// after: single frame
{"jsonrpc":"2.0","id":1,"method":"shutdown"} Defensive patterns
Strategy: try-catch
Validate before calling
// sender-side: validate the frame is a single, well-formed JSON-RPC message
var probe any
if err := json.Unmarshal(frame, &probe); err != nil {
return fmt.Errorf("bad frame JSON: %w", err)
}
m, ok := probe.(map[string]any)
if !ok || m["jsonrpc"] != "2.0" {
return fmt.Errorf("frame must be a single JSON-RPC 2.0 object")
} Type guard
func isSingleJsonRpcObject(frame []byte) bool {
var v any
if json.Unmarshal(frame, &v) != nil {
return false
}
m, ok := v.(map[string]any)
return ok && m["jsonrpc"] == "2.0"
} Try / catch
if _, err := reader.Read(); err != nil {
if errors.Is(err, lsproto.ErrorCodeInvalidRequest) {
// recoverable: skip the malformed frame, optionally send -32600 if an id was parsed
continue
}
return err
} Prevention
- Compute Content-Length in bytes (not runes) and never interleave other output on the message stream.
- Send single messages only; batch arrays are rejected.
- Keep proxies transparent — no BOM, no log lines inside the framing.
When it happens
Trigger: Sending a JSON-RPC frame that is an array (batch, unsupported shape here), a frame missing "method", a frame where "id" is an object, or invalid JSON bytes from a misframed Content-Length stream; any decode failure in Message.UnmarshalJSON outside the params stage.
Common situations: Broken Content-Length framing (length mismatch truncating JSON); clients sending batch requests; proxies inserting BOM or log lines into the stream; version skew where clients assume permissive base-protocol parsing.
Related errors
- -32602
- expected null, got %s
- api: unexpected message while waiting for %q response
- %w: expected binary data (0xc4-0xc6), received: 0x%02x
- missing required properties: %s
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/4a573d0b27a91021.
Report an issue: GitHub.