{"record":{"id":"cfe74a125a577e10","repo":"dotnet/aspnetcore","slug":"invalid-payload-for-streamitem-message-cfe74a","errorCode":null,"errorMessage":"Invalid payload for StreamItem message.","messagePattern":"Invalid payload for StreamItem message\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts","lineNumber":105,"sourceCode":"     * @returns {string} A string containing the serialized representation of the message.\n     */\n    public writeMessage(message: HubMessage): string {\n        return TextMessageFormat.write(JSON.stringify(message));\n    }\n\n    private _isInvocationMessage(message: InvocationMessage): void {\n        this._assertNotEmptyString(message.target, \"Invalid payload for Invocation message.\");\n\n        if (message.invocationId !== undefined) {\n            this._assertNotEmptyString(message.invocationId, \"Invalid payload for Invocation message.\");\n        }\n    }\n\n    private _isStreamItemMessage(message: StreamItemMessage): void {\n        this._assertNotEmptyString(message.invocationId, \"Invalid payload for StreamItem message.\");\n\n        if (message.item === undefined) {\n            throw new Error(\"Invalid payload for StreamItem message.\");\n        }\n    }\n\n    private _isCompletionMessage(message: CompletionMessage): void {\n        if (message.result && message.error) {\n            throw new Error(\"Invalid payload for Completion message.\");\n        }\n\n        if (!message.result && message.error) {\n            this._assertNotEmptyString(message.error, \"Invalid payload for Completion message.\");\n        }\n\n        this._assertNotEmptyString(message.invocationId, \"Invalid payload for Completion message.\");\n    }\n\n    private _isAckMessage(message: AckMessage): void {\n        if (typeof message.sequenceId !== 'number') {\n            throw new Error(\"Invalid SequenceId for Ack message.\");","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts#L87-L123","documentation":"A StreamItem message (type 2) must carry an `item` payload; an undefined item means the stream produced nothing, which the protocol treats as malformed because every StreamItem represents one emitted value.","triggerScenarios":"Server sends {\"type\":2,\"invocationId\":\"x\"} with the `item` field omitted or explicitly null-as-undefined. Happens when a streaming hub method yields null/undefined through a serializer that drops undefined keys.","commonSituations":"A server-side ChannelAsyncEnumerable yields null, a custom serializer strips undefined fields, or a JS server that does `yield undefined`.","solutions":["Ensure the streaming hub method never yields null/undefined; emit a concrete value or a sentinel object instead.","If using a custom JSON serializer, configure it to preserve keys even for null values.","Log the raw message (logMessageContent:true) to confirm whether `item` is missing on the wire.","Align server and client SignalR versions so serialization semantics match."],"exampleFix":"// server (TS hub) before\nasync function* stream() { yield undefined; }\n\n// after\nasync function* stream() { yield { value: null }; }","handlingStrategy":"validation","validationCode":"// server side: ensure every yielded item is defined\nasync function* stream() {\n  const v = await nextValue();\n  if (v === undefined) return; // stop instead of yielding undefined\n  yield v;\n}","typeGuard":"function hasItem(m: any): boolean {\n  return m?.type === 2 && m.item !== undefined;\n}","tryCatchPattern":"stream.subscribe({\n  next: (item) => { /* ... */ },\n  error: (e) => { /* stream-level errors surface here */ },\n});","preventionTips":["Streaming hub methods should never yield null/undefined; terminate the stream instead.","Configure server serializers to keep keys for null values if null is meaningful.","Unit-test streaming hubs against the real client to catch dropped items."],"tags":["typescript","signalr","protocol","streaming","validation"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}