dotnet/aspnetcore · error · Error
Invalid SequenceId for Ack message.
Error message
Invalid SequenceId for Ack message.
What it means
Thrown by JsonHubProtocol._isAckMessage when an Ack message's `sequenceId` is not of type `number`. Ack messages (part of the stateful-reconnect / sequence-id protocol extension) must carry a numeric sequenceId so the peer can acknowledge the highest contiguous message received.
Solutions
- Confirm both client and server support the stateful-reconnect (sequence/Ack) protocol extension.
- Inspect the Ack frame to verify sequenceId is present and numeric.
- If a gateway is in the path, ensure it does not rewrite or drop numeric fields.
Defensive patterns
Strategy: type-guard
Validate before calling
function validAck(m: any): boolean {
return typeof m?.sequenceId === "number";
} Type guard
function isNumericSequenceId(m: any): m is { sequenceId: number } {
return !!m && typeof m.sequenceId === "number" && Number.isFinite(m.sequenceId);
} Prevention
- Enable stateful reconnect on both client and server.
- Ensure gateways do not rewrite the sequenceId field.
- Validate Ack frames during integration testing.
When it happens
Trigger: Receiving a JSON message with `type` corresponding to Ack but whose `sequenceId` is missing, a string, null, or any non-number value. This typically originates from a malformed server response or a protocol-extension version mismatch.
Common situations: Enabling stateful reconnect on the client while the server runs a version that does not support it (or vice versa), or a proxy/gateway corrupting the sequenceId field.
Related errors
- Invalid SequenceId for Sequence message.
- Error reading JSON.
- errorMessage
- Invalid input for JSON hub protocol. Expected a string.
- Invalid payload.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/a47bdbd021f637b9.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts:123
throw new Error("Invalid payload for StreamItem message.");
}
}
private _isCompletionMessage(message: CompletionMessage): void {
if (message.result && message.error) {
throw new Error("Invalid payload for Completion message.");
}
if (!message.result && message.error) {
this._assertNotEmptyString(message.error, "Invalid payload for Completion message.");
}
this._assertNotEmptyString(message.invocationId, "Invalid payload for Completion message.");
}
private _isAckMessage(message: AckMessage): void {
if (typeof message.sequenceId !== 'number') {
throw new Error("Invalid SequenceId for Ack message.");
}
}
private _isSequenceMessage(message: SequenceMessage): void {
if (typeof message.sequenceId !== 'number') {
throw new Error("Invalid SequenceId for Sequence message.");
}
}
private _assertNotEmptyString(value: any, errorMessage: string): void {
if (typeof value !== "string" || value === "") {
throw new Error(errorMessage);
}
}
}
View on GitHub (pinned to 3600ca084e)