{"record":{"id":"842fff606255ff97","repo":"dotnet/aspnetcore","slug":"invalid-input-for-messagepack-hub-protocol-expect","errorCode":null,"errorMessage":"Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.","messagePattern":"Invalid input for MessagePack hub protocol\\. Expected an ArrayBuffer\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts","lineNumber":76,"sourceCode":"            messagePackOptions.extensionCodec,\n            messagePackOptions.context,\n            messagePackOptions.maxStrLength,\n            messagePackOptions.maxBinLength,\n            messagePackOptions.maxArrayLength,\n            messagePackOptions.maxMapLength,\n            messagePackOptions.maxExtLength,\n        );\n    }\n\n    /** Creates an array of HubMessage objects from the specified serialized representation.\n     *\n     * @param {ArrayBuffer} input An ArrayBuffer containing the serialized representation.\n     * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.\n     */\n    public parseMessages(input: ArrayBuffer, logger: ILogger): HubMessage[] {\n        // The interface does allow \"string\" to be passed in, but this implementation does not. So let's throw a useful error.\n        if (!(isArrayBuffer(input))) {\n            throw new Error(\"Invalid input for MessagePack hub protocol. Expected an ArrayBuffer.\");\n        }\n\n        if (logger === null) {\n            logger = NullLogger.instance;\n        }\n\n        const messages = BinaryMessageFormat.parse(input);\n\n        const hubMessages = [];\n        for (const message of messages) {\n            const parsedMessage = this._parseMessage(message, logger);\n            // Can be null for an unknown message. Unknown message is logged in parseMessage\n            if (parsedMessage) {\n                hubMessages.push(parsedMessage);\n            }\n        }\n\n        return hubMessages;","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts#L58-L94","documentation":"Thrown by MessagePackHubProtocol.parseMessages() when the incoming data is not an ArrayBuffer. The IHubProtocol interface technically permits string input, but this binary-only implementation rejects anything that fails isArrayBuffer() (a plain string, a Uint8Array, or a DataView). It exists because MessagePack is a binary transfer format and the @msgpack/msgpack decoder requires raw bytes. The guard at line 75 makes the mismatch fail fast with a clear message instead of corrupting deeper inside the decoder.","triggerScenarios":"Calling messagePackProtocol.parseMessages(someString, logger) where someString is a JS string; passing a Uint8Array or Node Buffer (both fail isArrayBuffer); wiring the protocol over a Text (non-binary) WebSocket transport that delivers string chunks.","commonSituations":"Migrating from the JSON protocol and forgetting that the transport must negotiate TransferFormat.Binary; a custom transport or proxy that re-encodes frames as text; a server that downgrades the connection to text format; older browsers/Node where fetch/XHR surface data as a non-ArrayBuffer type.","solutions":["Ensure the connection is created with a transport that supports binary (WebSockets default, or LongPolling/Fetch which handle binary) and that the server agrees on the messagepack protocol.","If you call parseMessages directly, convert the input first: parseMessages(myBuffer.buffer ? myBuffer.buffer : myBuffer, logger) for ArrayBuffer, or copy a Uint8Array via new Uint8Array(...).buffer.","Verify you are not feeding a string: wrap with new TextEncoder().encode(str) only if you genuinely have msgpack bytes serialized as a string (rare); otherwise switch to the JSON protocol.","Double-check that the data passed comes from a binary transferFormat connection (this.transferFormat === TransferFormat.Binary)."],"exampleFix":"// before\nconst messages = protocol.parseMessages(receivedString, logger);\n\n// after\n// only call with the underlying ArrayBuffer from a binary transport\nconst messages = protocol.parseMessages(receivedArrayBuffer, logger);","handlingStrategy":"validation","validationCode":"// before calling parseMessages, ensure binary input\nfunction toArrayBuffer(input: unknown): ArrayBuffer {\n  if (input instanceof ArrayBuffer) return input;\n  if (ArrayBuffer.isView(input as ArrayBufferView)) {\n    return (input as Uint8Array).buffer.slice(\n      (input as Uint8Array).byteOffset,\n      (input as Uint8Array).byteOffset + (input as Uint8Array).byteLength,\n    );\n  }\n  throw new TypeError('parseMessages requires an ArrayBuffer');\n}\nconst messages = protocol.parseMessages(toArrayBuffer(data), logger);","typeGuard":"import { isArrayBuffer } from '@microsoft/signalr-protocol-msgpack/dist/esm/Utils';\nfunction isParsable(data: unknown): data is ArrayBuffer {\n  return isArrayBuffer(data);\n}","tryCatchPattern":"try {\n  const messages = protocol.parseMessages(data as ArrayBuffer, logger);\n} catch (e) {\n  if (e.message.includes('Expected an ArrayBuffer')) {\n    // convert and retry, or report a transport misconfiguration\n    throw new Error('MessagePack protocol requires a binary transport');\n  }\n  throw e;\n}","preventionTips":["Always create the HubConnection over a transport negotiated for TransferFormat.Binary.","If you call parseMessages directly, normalize input through an ArrayBuffer coercion helper.","Unit-test the protocol path with both ArrayBuffer and Uint8Array to catch shape mismatches early."],"tags":["messagepack","validation","binary-protocol","typescript","input-validation"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}