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
- Confirm client and server run compatible SignalR protocol versions (the TS JSON protocol is version 2).
- Inspect the raw framed payload with logMessageContent:true to see the actual JSON and confirm `type` is present and numeric.
- Remove any proxy/middleware that alters the response body between server and client.
- 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
- Keep client and server on compatible SignalR protocol versions.
- Enable logMessageContent:true during integration to capture raw frames.
- Never inject non-SignalR JSON into the connection pipeline.
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
- Invalid input for JSON hub protocol. Expected a string.
- Invalid payload for StreamItem message.
- Invalid payload for Completion message.
- Invalid payload for Invocation message.
- Message is incomplete.
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/0b73b144e23012a1.
Report an issue: GitHub.