eyaltoledano/claude-task-master · critical
Failed to parse AI response as JSON: ${error.message}
Error message
Failed to parse AI response as JSON: ${error.message} What it means
When JSON path extraction fails, the parser tries the fallbackItemExtractor; if that also throws, handleFallbackError decides whether to surface the failure. If no items were parsed from streaming at all, it throws 'Failed to parse AI response as JSON: <reason>'. This means the AI output contained no parseable JSON matching any jsonPath and no items were recovered.
Source
Thrown at src/utils/stream-parser.js:318
// Only add items we haven't already parsed
const itemsToAdd = fallbackItems.slice(
this.progressTracker.parsedItems.length
);
const newItems = [];
for (const item of itemsToAdd) {
if (this.config.itemValidator(item)) {
newItems.push(item);
this.progressTracker.addItem(item);
}
}
return newItems;
}
handleFallbackError(error) {
if (this.progressTracker.parsedItems.length === 0) {
throw new Error(`Failed to parse AI response as JSON: ${error.message}`);
}
// If we have some items from streaming, continue with those
}
}
/**
* Buffer size validator
*/
class BufferSizeValidator {
constructor(maxSize) {
this.maxSize = maxSize;
this.currentSize = 0;
}
validateChunk(existingText, newChunk) {
const newSize = Buffer.byteLength(existingText + newChunk, 'utf8');
if (newSize > this.maxSize) {View on GitHub (pinned to c0c98d367c)
Solutions
- Log/inspect error.message from the thrown error to see the underlying JSON.parse failure and the raw response.
- Check jsonPaths matches the actual response structure (use the raw text to verify).
- Add/adjust the system prompt to force valid JSON-only output, or parse a fenced ```json block in fallbackItemExtractor.
- Increase max tokens or handle truncation so the JSON is not cut off mid-stream.
Example fix
// before
const parser = new StreamParser({ jsonPaths: ['$.items'] });
// after
const parser = new StreamParser({
jsonPaths: ['$.items', '$.data.items'], // cover actual response shapes
fallbackItemExtractor: (text) => {
const m = text.match(/```json\n([\s\S]*?)```/);
return m ? JSON.parse(m[1]).items : [];
}
}); Defensive patterns
Strategy: try-catch
Validate before calling
function looksLikeJson(text) {
const t = text.trim();
return t.startsWith('{') || t.startsWith('[') || /```json/.test(t);
}
// check accumulated stream text before final parse; if !looksLikeJson(text), surface/prompt-retry early Try / catch
try {
const items = await parser.parseStream(stream);
return items;
} catch (err) {
if (err.message.startsWith('Failed to parse AI response as JSON')) {
// no items recovered: retry with stricter JSON prompt or inspect raw text
logger.error('AI response not parseable', err.message);
return retryWithJsonOnlyPrompt();
}
throw err;
} Prevention
- Enforce JSON-only output in the system prompt and validate with a quick pre-parse.
- Configure jsonPaths to match the actual response nesting; test with real samples.
- Raise max tokens / handle truncation so JSON is not cut off.
- Provide a fallbackItemExtractor that can salvage fenced ```json blocks.
When it happens
Trigger: The model returned prose/markdown with no JSON; the response was truncated mid-JSON due to max tokens; jsonPath does not match the actual response shape (e.g. '$.items' but response nests under '$.data.items'); streaming produced zero items and then a JSON.parse error occurred during final parsing.
Common situations: Changing the prompt so the model stops emitting JSON; asking for output in a different shape than the configured jsonPaths; truncated responses from token limits; the stream erroring before any items were emitted so there is nothing to fall back on.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse JSON response: ${parseError.message}. Respon
- CONFIG_ERROR
- Invalid conventional commit format
- Invalid JSON in file ${filePath}: ${error.message}
- Corrupted JSON in ${filePath}: ${err.message}. File contains
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/a92f931bfaabff9f.
Report an issue: GitHub.