dotnet/aspnetcore · error · Error

Invalid input for JSON hub protocol. Expected a string.

Error message

Invalid input for JSON hub protocol. Expected a string.

What it means

JsonHubProtocol only operates on TransferFormat.Text, so parseMessages requires a string. Passing an ArrayBuffer (or any non-string) violates the protocol contract: the interface permits ArrayBuffer for binary protocols, but the JSON implementation does not, so it throws an explicit error rather than failing mysteriously inside JSON.parse.

Source

Thrown at src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts:31

export class JsonHubProtocol implements IHubProtocol {

    /** @inheritDoc */
    public readonly name: string = JSON_HUB_PROTOCOL_NAME;
    /** @inheritDoc */
    public readonly version: number = 2;

    /** @inheritDoc */
    public readonly transferFormat: TransferFormat = TransferFormat.Text;

    /** Creates an array of {@link @microsoft/signalr.HubMessage} objects from the specified serialized representation.
     *
     * @param {string} input A string containing the serialized representation.
     * @param {ILogger} logger A logger that will be used to log messages that occur during parsing.
     */
    public parseMessages(input: string, logger: ILogger): HubMessage[] {
        // The interface does allow "ArrayBuffer" to be passed in, but this implementation does not. So let's throw a useful error.
        if (typeof input !== "string") {
            throw new Error("Invalid input for JSON hub protocol. Expected a string.");
        }

        if (!input) {
            return [];
        }

        if (logger === null) {
            logger = NullLogger.instance;
        }

        // Parse the messages
        const messages = TextMessageFormat.parse(input);

        const hubMessages = [];
        for (const message of messages) {
            const parsedMessage = JSON.parse(message) as HubMessage;
            if (typeof parsedMessage.type !== "number") {
                throw new Error("Invalid payload.");

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Ensure the hub protocol matches the transport's transfer format: JsonHubProtocol with Text, MessagePackHubProtocol with Binary.
  2. If you call parseMessages directly, coerce/decode the payload to a string first (e.g. new TextDecoder().decode(buffer)).
  3. Check that you did not accidentally pass an ArrayBuffer through a custom IHubProtocol decorator to the JSON protocol.
  4. Verify HttpConnectionOptions.transport and the negotiated protocol agree on text vs binary.

Example fix

// before
const protocol = new JsonHubProtocol();
protocol.parseMessages(buffer /* ArrayBuffer */, logger); // throws

// after
const text = typeof input === 'string' ? input : new TextDecoder().decode(input);
protocol.parseMessages(text, logger);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof input !== 'string') {
  throw new TypeError('JsonHubProtocol.parseMessages requires a string; got ' + typeof input);
}
// or decode before calling
const text = typeof input === 'string' ? input : new TextDecoder().decode(input as ArrayBuffer);

Type guard

function isStringPayload(v: unknown): v is string {
  return typeof v === 'string';
}

Try / catch

try {
  protocol.parseMessages(text, logger);
} catch (e) {
  if (e instanceof Error && e.message.includes('Expected a string')) {
    // wrong protocol/transport pairing
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling JsonHubProtocol.parseMessages with an ArrayBuffer, or wiring a transport that delivers binary chunks (e.g. a MessagePack-style transport) into a JsonHubProtocol instance. Also triggered by a custom IHubProtocol wrapper that forwards raw bytes.

Common situations: Mixing the JSON hub protocol with a binary transfer format by accident, a custom transport that does not decode to string, or upgrading a MessagePack setup and forgetting to swap the protocol object.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/c65b6e9400697642. Report an issue: GitHub.