microsoft/typescript-go · error · ErrInvalidRequest

%w: unknown message type: %d

Error message

%w: unknown message type: %d

What it means

The type integer parsed successfully but its value is outside the valid range MessageTypeRequest..MessageTypeCall (1..6); 0 is 'unknown' and values above 6 are undefined in this build. Wraps ErrInvalidRequest, making it programmatically distinguishable from transport errors.

Source

Thrown at internal/api/protocol_msgpack.go:126

	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 {
		return 0, "", nil, fmt.Errorf("%w: expected positive fixint or uint8 marker, received: 0x%02x", ErrInvalidRequest, t)
	}
	msgType := MessageType(rawType)
	if !msgType.IsValid() {
		return 0, "", nil, fmt.Errorf("%w: unknown message type: %d", ErrInvalidRequest, msgType)
	}

	// Read method (binary)
	methodBytes, err := p.readBin()
	if err != nil {
		return 0, "", nil, err
	}
	method := string(methodBytes)

	// Read payload (binary)
	payload, err := p.readBin()
	if err != nil {
		return 0, "", nil, err
	}

	return msgType, method, payload, nil
}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Align both ends to the same typescript-go version
  2. Treat unknown types as fatal for the connection - the frame layout cannot be assumed; close it
  3. If you control the peer, restrict emitted types to the shared known set
  4. Log the value: 7+ strongly suggests a newer protocol than this reader

Example fix

// before
writeTuple(MessageType(9), ...) // undefined type

// after
writeTuple(MessageTypeRequest, ...) // value in 1..6
Defensive patterns

Strategy: try-catch

Type guard

// Only for peers you control: restrict emitted types to the shared valid set.
func validMessageType(t api.MessageType) bool { return t.IsValid() }

Try / catch

if err != nil && errors.Is(err, api.ErrInvalidRequest) {
	if strings.Contains(err.Error(), "unknown message type") {
		// peer speaks a newer protocol; reconnect with matched versions
		return reconnectWithPinnedVersion()
	}
}

Prevention

When it happens

Trigger: A peer on a newer protocol that defined additional message types; a corrupted type byte; hand-crafted frames with arbitrary type values.

Common situations: Forward-compatibility breaks when one side is upgraded first; fuzzed input into the reader; experimental forks adding message types.

Related errors


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