dotnet/aspnetcore · error · Error
Invalid payload for Completion message.
Error message
Invalid payload for Completion message.
What it means
Thrown by JsonHubProtocol._isCompletionMessage for three distinct malformed-Completion conditions: (1) both `result` and `error` are truthy, (2) `error` is truthy but `result` is falsy AND `error` is not a non-empty string, or (3) `invocationId` is not a non-empty string. A well-formed Completion carries exactly one of error/result and always a non-empty invocationId.
Solutions
- Ensure the server sets either `result` or `error` (never both) on Completion.
- Make sure error is a non-empty string when present.
- Always include the invocationId matching the originating invocation/stream.
Defensive patterns
Strategy: validation
Validate before calling
function validCompletion(m: any): boolean {
const hasResult = !!m.result;
const hasErr = !!m.error;
if (hasResult && hasErr) return false;
if (hasErr && !hasResult && (typeof m.error !== "string" || m.error === "")) return false;
return typeof m.invocationId === "string" && m.invocationId !== "";
} Type guard
function isWellFormedCompletion(m: any): boolean {
if (!m) return false;
if (m.result && m.error) return false;
if (m.error && typeof m.error !== "string") return false;
return typeof m.invocationId === "string" && m.invocationId.length > 0;
} Prevention
- Set exactly one of result or error on Completion.
- Provide a non-empty error string.
- Always include the originating invocationId.
When it happens
Trigger: Server returns a Completion message where: result and error are both set; error is set to an empty string or non-string; or invocationId is missing/empty. Also triggered by a malformed/injected frame.
Common situations: Server hub method throws but the error serializer emits an empty message, a proxy rewrites the payload dropping invocationId, or a hand-written server implementation that populates result and error together.
Related errors
- errorMessage
- Invalid payload.
- Error reading JSON.
- Invalid input for JSON hub protocol. Expected a string.
- Invalid payload for StreamItem message.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/a432ec2fb22f57db.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts:111
private _isInvocationMessage(message: InvocationMessage): void {
this._assertNotEmptyString(message.target, "Invalid payload for Invocation message.");
if (message.invocationId !== undefined) {
this._assertNotEmptyString(message.invocationId, "Invalid payload for Invocation message.");
}
}
private _isStreamItemMessage(message: StreamItemMessage): void {
this._assertNotEmptyString(message.invocationId, "Invalid payload for StreamItem message.");
if (message.item === undefined) {
throw new Error("Invalid payload for StreamItem message.");
}
}
private _isCompletionMessage(message: CompletionMessage): void {
if (message.result && message.error) {
throw new Error("Invalid payload for Completion message.");
}
if (!message.result && message.error) {
this._assertNotEmptyString(message.error, "Invalid payload for Completion message.");
}
this._assertNotEmptyString(message.invocationId, "Invalid payload for Completion message.");
}
private _isAckMessage(message: AckMessage): void {
if (typeof message.sequenceId !== 'number') {
throw new Error("Invalid SequenceId for Ack message.");
}
}
private _isSequenceMessage(message: SequenceMessage): void {
if (typeof message.sequenceId !== 'number') {
throw new Error("Invalid SequenceId for Sequence message.");View on GitHub (pinned to 3600ca084e)