dotnet/aspnetcore · error · Error

Invalid payload.

Error message

Invalid payload.

What it means

After JSON.parse, each framed message must carry a numeric `type` field so the protocol can dispatch it (Invocation=1, StreamItem=2, Completion=3, etc.). When `type` is missing, null, or non-numeric the protocol cannot route the message and rejects the whole batch.

Source

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

            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.");
            }
            switch (parsedMessage.type) {
                case MessageType.Invocation:
                    this._isInvocationMessage(parsedMessage);
                    break;
                case MessageType.StreamItem:
                    this._isStreamItemMessage(parsedMessage);
                    break;
                case MessageType.Completion:
                    this._isCompletionMessage(parsedMessage);
                    break;
                case MessageType.Ping:
                    // Single value, no need to validate
                    break;
                case MessageType.Close:
                    // All optional values, no need to validate
                    break;
                case MessageType.Ack:

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Confirm client and server run compatible SignalR protocol versions (the TS JSON protocol is version 2).
  2. Inspect the raw framed payload with logMessageContent:true to see the actual JSON and confirm `type` is present and numeric.
  3. Remove any proxy/middleware that alters the response body between server and client.
  4. If building messages manually, always include a numeric `type` from the MessageType enum.

Example fix

// before
const bad = '{"target":"Do"}'; // no type field

// after
const ok = '{"type":1,"target":"Do","arguments":[]}';
Defensive patterns

Strategy: try-catch

Validate before calling

// If you build messages, validate before send
function validHubMessage(m: any): boolean {
  return typeof m?.type === 'number';
}

Type guard

function isHubMessage(v: any): v is { type: number } {
  return v != null && typeof v.type === 'number';
}

Try / catch

try {
  hubConnection.start();
} catch (e) {
  // protocol-level parse errors usually surface via onclose; inspect raw logs
  if (e instanceof Error && e.message === 'Invalid payload.') {
    // enable logMessageContent to capture the offending JSON
  }
}

Prevention

When it happens

Trigger: A server (or middleware/proxy) emits a JSON object without a `type` property, or sends `type` as a string like "1". Also occurs if a non-SignalR JSON payload reaches the parser, or if message framing splits a JSON object in half.

Common situations: Client/server protocol version mismatch, a reverse proxy or CDN rewriting/stripping fields, a hand-rolled server that omits `type`, or corrupted transport data producing a partial JSON object.

Related errors


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