dotnet/aspnetcore · error · Error
Invalid message type.
Error message
Invalid message type.
What it means
Thrown in the write path (writeMessage switch default) when asked to serialize a HubMessage whose type is not one of Invocation, StreamInvocation, Completion, Ping, CancelInvocation, Close, Ack, or Sequence. It is a programmer-error guard: you constructed or passed a HubMessage with an unknown/invalid MessageType enum value.
Solutions
- Verify the message.type is a known MessageType enum value before calling write.
- Align @microsoft/signalr and @microsoft/signalr-protocol-msgpack to the same version so the enum mapping is consistent.
- If writing a new message kind, you are extending the protocol — branch on type explicitly rather than relying on the default arm.
Example fix
// before
protocol.write({ type: 99, ... }); // unknown enum → throws
// after — guard known types before write
if (!Object.values(MessageType).includes(msg.type)) {
throw new TypeError(`Refusing to write unknown MessageType ${msg.type}`);
}
const bytes = protocol.write(msg); Defensive patterns
Strategy: validation
Validate before calling
const SERIALIZABLE = new Set([MessageType.Invocation, MessageType.StreamInvocation, MessageType.Completion, MessageType.Ping, MessageType.CancelInvocation, MessageType.Close, MessageType.Ack, MessageType.Sequence]);
function isSerializableMessageType(t: unknown): boolean {
return SERIALIZABLE.has(t as MessageType);
}
if (!isSerializableMessageType(msg.type)) throw new TypeError(`Unsupported MessageType ${msg.type}`); Type guard
function isKnownMessageType(t: unknown): t is MessageType {
return typeof t === 'number' && t >= 1 && t <= 7 || t === 8 || t === 9;
} Try / catch
try { return protocol.write(msg); }
catch (e) {
if (/Invalid message type/.test((e as Error).message)) {
throw new TypeError(`Refusing to serialize message of type ${(msg as any).type}`);
}
throw e;
} Prevention
- Always construct HubMessages via the documented factory methods.
- Pin @microsoft/signalr and @microsoft/signalr-protocol-msgpack to the same version.
- Do not extend MessageType without also extending the protocol's write/parse branches.
When it happens
Trigger: Calling protocol.write(...) (directly or via HubConnection.send/invoke/stream) with a hand-built message whose type field is undefined, numeric garbage, or a future enum value the protocol version does not know how to serialize.
Common situations: Building custom HubMessage objects; mismatched @microsoft/signalr-protocol-msgpack version vs @microsoft/signalr (MessageType enum drift); a stale message object captured before an upgrade.
Related errors
- Error reading MessagePack data.
- Error writing MessagePack data.
- Unexpected message type
- Cannot read message size.
- Error reading length header.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/cdfed5c6fd69dd6b.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts:123
return this._writeInvocation(message as InvocationMessage);
case MessageType.StreamInvocation:
return this._writeStreamInvocation(message as StreamInvocationMessage);
case MessageType.StreamItem:
return this._writeStreamItem(message as StreamItemMessage);
case MessageType.Completion:
return this._writeCompletion(message as CompletionMessage);
case MessageType.Ping:
return BinaryMessageFormat.write(SERIALIZED_PING_MESSAGE);
case MessageType.CancelInvocation:
return this._writeCancelInvocation(message as CancelInvocationMessage);
case MessageType.Close:
return this._writeClose();
case MessageType.Ack:
return this._writeAck(message as AckMessage);
case MessageType.Sequence:
return this._writeSequence(message as SequenceMessage);
default:
throw new Error("Invalid message type.");
}
}
private _parseMessage(input: Uint8Array, logger: ILogger): HubMessage | null {
if (input.length === 0) {
throw new Error("Invalid payload.");
}
const properties = this._decoder.decode(input) as any;
if (properties.length === 0 || !(properties instanceof Array)) {
throw new Error("Invalid payload.");
}
const messageType = properties[0] as MessageType;
switch (messageType) {
case MessageType.Invocation:
return this._createInvocationMessage(this._readHeaders(properties), properties);View on GitHub (pinned to 3600ca084e)