{"record":{"id":"87c234ddde00dc01","repo":"eyaltoledano/claude-task-master","slug":"stream-processing-failed","errorCode":"STREAM_PROCESSING_FAILED","errorMessage":"Failed to process AI text stream: ${error.message}","messagePattern":"Failed to process AI text stream: (.+?)","errorType":"exception","errorClass":"StreamingError","httpStatus":null,"severity":"error","filePath":"src/utils/stream-parser.js","lineNumber":396,"sourceCode":"\t\t\tthis.progressTracker.addText(chunk);\n\t\t\tthis.jsonParser.write(chunk);\n\t\t});\n\n\t\ttry {\n\t\t\tawait processor.process(textStream);\n\t\t} catch (streamError) {\n\t\t\tthis.handleStreamError(streamError);\n\t\t}\n\n\t\tthis.jsonParser.end();\n\t}\n\n\thandleStreamError(error) {\n\t\t// Re-throw StreamingError as-is, wrap other errors\n\t\tif (error instanceof StreamingError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new StreamingError(\n\t\t\t`Failed to process AI text stream: ${error.message}`,\n\t\t\tSTREAMING_ERROR_CODES.STREAM_PROCESSING_FAILED\n\t\t);\n\t}\n\n\tasync waitForParsingCompletion() {\n\t\t// Wait for final parsing to complete (JSON parser may still be processing)\n\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t}\n\n\tasync attemptFallbackIfNeeded() {\n\t\tconst fallbackItems = await this.fallbackParser.attemptParsing();\n\t\treturn fallbackItems.length > 0;\n\t}\n\n\tbuildResult(usedFallback) {\n\t\tconst metadata = this.progressTracker.getMetadata();\n","sourceCodeStart":378,"sourceCodeEnd":414,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/src/utils/stream-parser.js#L378-L414","documentation":"handleStreamError is the StreamParser's central error wrapper, invoked from processStream. Any non-StreamingError thrown while reading or processing the AI text stream (I/O failures, unexpected stream termination, JSON decode explosions) is wrapped in a StreamingError with code STREAM_PROCESSING_FAILED, preserving the original message. StreamingError instances are re-thrown untouched so callers can branch on the specific code.","triggerScenarios":"The text stream emits malformed bytes that crash both the JSONStreamParser and FallbackParser; the underlying stream emits an 'error' event (connection dropped mid-response); an exception inside progressTracker callbacks or waitForParsingCompletion; any bug thrown inside processStream's iteration loop.","commonSituations":"LLM providers closing the connection mid-stream under load; proxy/timeouts truncating the response; the parser receiving a stream in an unexpected encoding; upgrading the AI SDK so the stream object no longer implements the async-iterator interface the parser expects.","solutions":["Read error.message to identify the underlying cause, and check error.code === 'STREAM_PROCESSING_FAILED' to confirm it came from this wrapper.","Add retry logic around the whole stream fetch + parse operation for transient network drops.","Validate the stream source (encoding, availability) before passing it to parse().","If the cause is a bug in your own progressTracker/config callbacks, fix the callback rather than handling the wrapper.","Catch StreamingError specifically so other errors (like [510]'s plain Error) remain distinct."],"exampleFix":"// before\nconst result = await parser.parse(stream);\n// after\ntry {\n  const result = await parser.parse(stream);\n} catch (err) {\n  if (err.code === 'STREAM_PROCESSING_FAILED') {\n    console.error('Stream processing failed, retrying:', err.message);\n    return await retryWithBackoff(() => parser.parse(fetchStream()));\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"function isUsableStream(stream) {\n  return stream != null &&\n    (typeof stream[Symbol.asyncIterator] === 'function' || typeof stream.on === 'function');\n}\nif (!isUsableStream(stream)) {\n  throw new TypeError('parse() expects a string or readable/async-iterable stream');\n}","typeGuard":"function isStreamingError(err) {\n  return err instanceof Error && typeof err.code === 'string' && err.name === 'StreamingError';\n}","tryCatchPattern":"import { StreamingError } from './streaming-error.js';\ntry {\n  await parser.parse(stream);\n} catch (err) {\n  if (err instanceof StreamingError && err.code === 'STREAM_PROCESSING_FAILED') {\n    console.error('Underlying cause:', err.message);\n    // retry with fresh stream or fall back to non-streaming request\n  } else {\n    throw err;\n  }\n}","preventionTips":["Add retries with backoff around stream fetch + parse for transient network drops.","Monitor provider status; mid-stream disconnects often correlate with provider incidents.","Keep progress tracker callbacks exception-free — a throw there surfaces as this wrapper.","Pin/verify your AI SDK version so stream objects keep the expected iterator interface."],"tags":["streaming","error-wrapping","network","llm"],"backgroundTag":"stream-processing-failed","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}