microsoft/typescript-go · error · ErrInvalidRequest
%w: expected fixed 3-element array (0x93), received: 0x%02x
Error message
%w: expected fixed 3-element array (0x93), received: 0x%02x
What it means
The first byte of every frame must be the msgpack fixed-array-3 marker 0x93 because each message is a [type, method, payload] tuple. Anything else means the byte stream is not aligned to a message boundary - desynchronized, corrupted, or an entirely different wire format. Wraps ErrInvalidRequest so it is detectable with errors.Is.
Source
Thrown at internal/api/protocol_msgpack.go:103
msg.Error = &jsonrpc.ResponseError{
Code: jsonrpc.CodeInternalError,
Message: string(payload),
}
default:
return nil, fmt.Errorf("unexpected message type: %d", msgType)
}
return msg, nil
}
func (p *MessagePackProtocol) readTuple() (MessageType, string, []byte, error) {
// Read fixed array marker (0x93 = 3-element array)
t, err := p.r.ReadByte()
if err != nil {
return 0, "", nil, err
}
if t != msgpackFixedArray3 {
return 0, "", nil, fmt.Errorf("%w: expected fixed 3-element array (0x93), received: 0x%02x", ErrInvalidRequest, t)
}
// Read message type - can be positive fixint (0x00-0x7F) or uint8 (0xCC + value)
t, err = p.r.ReadByte()
if err != nil {
return 0, "", nil, err
}
var rawType byte
if t <= 0x7F {
// Positive fixint - the byte IS the value
rawType = t
} else if t == msgpackU8 {
// uint8 marker - next byte is the value
rawType, err = p.r.ReadByte()
if err != nil {
return 0, "", nil, err
}
} else {View on GitHub (pinned to 1bcfa18d79)
Solutions
- Confirm both endpoints were built with NewMessagePackProtocol over the same transport
- Ensure exactly one bufio.Reader wraps the connection; sharing it desyncs offsets
- When bridging from JSON/LSP, write an explicit translator rather than raw passthrough
- Inspect the offending byte: 0x7b ('{') indicates JSON framing; 0x43 indicates 'Content-Length:' headers
Example fix
// before
r := bufio.NewReader(conn); r2 := bufio.NewReader(conn) // two readers!
// after
br := bufio.NewReader(conn)
proto := api.NewMessagePackProtocol(readWriter{Reader: br, Writer: conn}) Defensive patterns
Strategy: try-catch
Try / catch
err := proto.ReadMessage()
if err != nil && errors.Is(err, api.ErrInvalidRequest) {
// framing desync: the byte stream cannot be recovered; close the connection
log.Printf("protocol desync: %v", err)
conn.Close()
} Prevention
- Construct both ends with NewMessagePackProtocol over one transport
- Wrap the conn in exactly one bufio.Reader
- Inspect the reported byte: 0x7b means JSON is being spoken; add a translator
When it happens
Trigger: A prior partial read left stray bytes; the peer speaks plain JSON-RPC or LSP Content-Length framing on this connection; two bufio.Readers sharing one conn stealing bytes from each other.
Common situations: Mixing protocol implementations on one pipe; proxies mangling bytes; constructing the protocol over a conn that something else also reads.
Related errors
- %w: expected positive fixint or uint8 marker, received: 0x%0
- ErrInvalidRequest
- api: unexpected message while waiting for %q response
- unexpected message type: %d
- %w: unknown message type: %d
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/131a5627c467c33b.
Report an issue: GitHub.