{"record":{"id":"28f4afd81ee30520","repo":"eyaltoledano/claude-task-master","slug":"stream-not-iterable","errorCode":"STREAM_NOT_ITERABLE","errorMessage":"Stream object is not iterable - no textStream, fullStream, or direct async iterator found","messagePattern":"Stream object is not iterable - no textStream, fullStream, or direct async iterator found","errorType":"exception","errorClass":"StreamingError","httpStatus":null,"severity":"error","filePath":"src/utils/stream-parser.js","lineNumber":171,"sourceCode":"\t}\n\n\tdetectStreamType(textStream) {\n\t\t// Check for textStream property\n\t\tif (this.hasAsyncIterator(textStream?.textStream)) {\n\t\t\treturn (stream) => this.processTextStream(stream.textStream);\n\t\t}\n\n\t\t// Check for fullStream property\n\t\tif (this.hasAsyncIterator(textStream?.fullStream)) {\n\t\t\treturn (stream) => this.processFullStream(stream.fullStream);\n\t\t}\n\n\t\t// Check if stream itself is iterable\n\t\tif (this.hasAsyncIterator(textStream)) {\n\t\t\treturn (stream) => this.processDirectStream(stream);\n\t\t}\n\n\t\tthrow new StreamingError(\n\t\t\t'Stream object is not iterable - no textStream, fullStream, or direct async iterator found',\n\t\t\tSTREAMING_ERROR_CODES.STREAM_NOT_ITERABLE\n\t\t);\n\t}\n\n\thasAsyncIterator(obj) {\n\t\treturn obj && typeof obj[Symbol.asyncIterator] === 'function';\n\t}\n\n\tasync processTextStream(stream) {\n\t\tfor await (const chunk of stream) {\n\t\t\tthis.onChunk(chunk);\n\t\t}\n\t}\n\n\tasync processFullStream(stream) {\n\t\tfor await (const chunk of stream) {\n\t\t\tif (chunk.type === 'text-delta' && chunk.textDelta) {","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/src/utils/stream-parser.js#L153-L189","documentation":"detectStreamType inspects the stream object for a textStream, a fullStream, or a direct async iterator; if none is found it throws this StreamingError with code STREAM_NOT_ITERABLE. It means the value passed to the parser cannot be consumed by any supported streaming strategy.","triggerScenarios":"Calling parseStream()/streamHandler with a plain object (e.g. an SDK result wrapper needing .textStream), a Promise that was not awaited, a string, or a stream from an incompatible SDK version where the iterator lives under a different property.","commonSituations":"Forgetting to await an async factory returning the stream; upgrading an AI SDK and property names changing; passing a Response object instead of its body reader; passing a Node Readable that lacks Symbol.asyncIterator (older polyfills).","solutions":["Await the call that produces the stream before passing it: await client.stream(...).","Pass the correct inner stream: result.textStream or result.fullStream instead of the wrapper object.","Verify the object has Symbol.asyncIterator: console.log(typeof stream[Symbol.asyncIterator]).","Log Object.keys(stream) to find the right stream property for your SDK version."],"exampleFix":"// before\nconst parser = new StreamParser({ jsonPaths: ['$.items'] });\nparser.parseStream(client.chat.completions.create({ stream: true }))\n// after\nconst result = await client.chat.completions.create({ stream: true });\nparser.parseStream(result.textStream)","handlingStrategy":"type-guard","validationCode":"function assertIterableStream(stream) {\n  if (\n    !stream ||\n    (typeof stream[Symbol.asyncIterator] !== 'function' &&\n      typeof stream.textStream?.[Symbol.asyncIterator] !== 'function' &&\n      typeof stream.fullStream?.[Symbol.asyncIterator] !== 'function')\n  ) {\n    throw new TypeError('Provided value is not a consumable stream (no textStream/fullStream/asyncIterator)');\n  }\n  return stream;\n}\nparser.parseStream(assertIterableStream(maybeStream));","typeGuard":"function isConsumableStream(v) {\n  return Boolean(\n    v &&\n    (typeof v[Symbol.asyncIterator] === 'function' ||\n      (v.textStream && typeof v.textStream[Symbol.asyncIterator] === 'function') ||\n      (v.fullStream && typeof v.fullStream[Symbol.asyncIterator] === 'function'))\n  );\n}","tryCatchPattern":"try {\n  await parser.parseStream(result);\n} catch (err) {\n  if (err.code === 'STREAM_NOT_ITERABLE') {\n    const inner = result?.textStream ?? result?.fullStream ?? result;\n    return parser.parseStream(inner);\n  }\n  throw err;\n}","preventionTips":["Always await async factories before passing their result as the stream.","Pass result.textStream or result.fullStream, not the SDK response wrapper.","After SDK upgrades, re-check the stream property names against the new API docs.","Debug with Object.keys(result) when unsure where the iterator lives."],"tags":["streaming","async-iterator","api-usage"],"backgroundTag":"stream-not-iterable","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}