microsoft/typescript-go · error · ErrInvalidRequest

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

Solutions

  1. Confirm both endpoints were built with NewMessagePackProtocol over the same transport
  2. Ensure exactly one bufio.Reader wraps the connection; sharing it desyncs offsets
  3. When bridging from JSON/LSP, write an explicit translator rather than raw passthrough
  4. 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

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


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/131a5627c467c33b. Report an issue: GitHub.

Appendix: 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)