{"record":{"id":"a47bdbd021f637b9","repo":"dotnet/aspnetcore","slug":"invalid-sequenceid-for-ack-message","errorCode":null,"errorMessage":"Invalid SequenceId for Ack message.","messagePattern":"Invalid SequenceId for Ack message\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts","lineNumber":123,"sourceCode":"            throw new Error(\"Invalid payload for StreamItem message.\");\n        }\n    }\n\n    private _isCompletionMessage(message: CompletionMessage): void {\n        if (message.result && message.error) {\n            throw new Error(\"Invalid payload for Completion message.\");\n        }\n\n        if (!message.result && message.error) {\n            this._assertNotEmptyString(message.error, \"Invalid payload for Completion message.\");\n        }\n\n        this._assertNotEmptyString(message.invocationId, \"Invalid payload for Completion message.\");\n    }\n\n    private _isAckMessage(message: AckMessage): void {\n        if (typeof message.sequenceId !== 'number') {\n            throw new Error(\"Invalid SequenceId for Ack message.\");\n        }\n    }\n\n    private _isSequenceMessage(message: SequenceMessage): void {\n        if (typeof message.sequenceId !== 'number') {\n            throw new Error(\"Invalid SequenceId for Sequence message.\");\n        }\n    }\n\n    private _assertNotEmptyString(value: any, errorMessage: string): void {\n        if (typeof value !== \"string\" || value === \"\") {\n            throw new Error(errorMessage);\n        }\n    }\n}\n","sourceCodeStart":105,"sourceCodeEnd":139,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts#L105-L139","documentation":"An Ack message (type 8) is part of the reliable-transport extension and carries a numeric `sequenceId` that the receiver acknowledges. A non-numeric sequenceId breaks the contiguous-sequence contract used to detect lost or duplicated messages.","triggerScenarios":"Server sends {\"type\":8,\"sequenceId\":\"5\"} (string) or omits sequenceId while reliable sessions are negotiated. Occurs when only one side enables the reliable protocol feature.","commonSituations":"Client/server version skew where one side supports reliable sessions (ack/sequence) and the other sends a malformed ack, or a hand-built server emitting a string sequenceId.","solutions":["Ensure both client and server run SignalR versions that agree on reliable-session support.","Confirm the server emits sequenceId as a JSON number, not a string.","Disable reliable sessions on the server if the client does not support them, or upgrade the client.","Inspect the raw ack message with logMessageContent:true."],"exampleFix":"// before\n{ \"type\": 8, \"sequenceId\": \"5\" }\n\n// after\n{ \"type\": 8, \"sequenceId\": 5 }","handlingStrategy":"type-guard","validationCode":"function validAck(m: any): boolean {\n  return m?.type === 8 && typeof m.sequenceId === 'number';\n}","typeGuard":"function isAckMessage(m: any): m is { type: 8; sequenceId: number } {\n  return m?.type === 8 && typeof m.sequenceId === 'number';\n}","tryCatchPattern":null,"preventionTips":["Ensure sequenceId is serialized as a JSON number on both ends.","Align client/server versions so reliable-session support is consistent.","Disable reliable sessions if either side cannot emit numeric sequenceIds."],"tags":["typescript","signalr","protocol","reliable-sessions","type-mismatch"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}