eyaltoledano/claude-task-master · error · StreamingError
STREAM_NOT_ITERABLE
STREAM_NOT_ITERABLE
Error message
Stream object is not iterable - no textStream, fullStream, or direct async iterator found
What it means
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.
Source
Thrown at src/utils/stream-parser.js:171
}
detectStreamType(textStream) {
// Check for textStream property
if (this.hasAsyncIterator(textStream?.textStream)) {
return (stream) => this.processTextStream(stream.textStream);
}
// Check for fullStream property
if (this.hasAsyncIterator(textStream?.fullStream)) {
return (stream) => this.processFullStream(stream.fullStream);
}
// Check if stream itself is iterable
if (this.hasAsyncIterator(textStream)) {
return (stream) => this.processDirectStream(stream);
}
throw new StreamingError(
'Stream object is not iterable - no textStream, fullStream, or direct async iterator found',
STREAMING_ERROR_CODES.STREAM_NOT_ITERABLE
);
}
hasAsyncIterator(obj) {
return obj && typeof obj[Symbol.asyncIterator] === 'function';
}
async processTextStream(stream) {
for await (const chunk of stream) {
this.onChunk(chunk);
}
}
async processFullStream(stream) {
for await (const chunk of stream) {
if (chunk.type === 'text-delta' && chunk.textDelta) {View on GitHub (pinned to c0c98d367c)
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.
Example fix
// before
const parser = new StreamParser({ jsonPaths: ['$.items'] });
parser.parseStream(client.chat.completions.create({ stream: true }))
// after
const result = await client.chat.completions.create({ stream: true });
parser.parseStream(result.textStream) Defensive patterns
Strategy: type-guard
Validate before calling
function assertIterableStream(stream) {
if (
!stream ||
(typeof stream[Symbol.asyncIterator] !== 'function' &&
typeof stream.textStream?.[Symbol.asyncIterator] !== 'function' &&
typeof stream.fullStream?.[Symbol.asyncIterator] !== 'function')
) {
throw new TypeError('Provided value is not a consumable stream (no textStream/fullStream/asyncIterator)');
}
return stream;
}
parser.parseStream(assertIterableStream(maybeStream)); Type guard
function isConsumableStream(v) {
return Boolean(
v &&
(typeof v[Symbol.asyncIterator] === 'function' ||
(v.textStream && typeof v.textStream[Symbol.asyncIterator] === 'function') ||
(v.fullStream && typeof v.fullStream[Symbol.asyncIterator] === 'function'))
);
} Try / catch
try {
await parser.parseStream(result);
} catch (err) {
if (err.code === 'STREAM_NOT_ITERABLE') {
const inner = result?.textStream ?? result?.fullStream ?? result;
return parser.parseStream(inner);
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Failed to generate tasks using generateObject fallback
- Schema is required for object streaming
- jsonPaths is required and must be an array
- jsonPaths array cannot be empty
- Failed to parse AI response as JSON: ${error.message}
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/28f4afd81ee30520.
Report an issue: GitHub.