eyaltoledano/claude-task-master · error · MCPError

Failed to parse JSON response: ${parseError.message}. Respon

Error message

Failed to parse JSON response: ${parseError.message}. Response: ${result.text.substring(0, 200)}...

What it means

doGenerateObject expects the model's text output to be JSON and calls JSON.parse on it; when parsing fails it wraps the syntax error in an MCPError that includes the parser message and the first 200 characters of the response for debugging. The model returned non-JSON text (prose, markdown fences, truncated output) instead of a JSON object.

Source

Thrown at mcp-server/src/custom-sdk/language-model.js:150

					includeContext: 'thisServer'
				},
				{
					timeout: 240000 // 4 minutes timeout
				}
			);

			// Convert MCP response back to AI SDK format
			const result = convertFromMCPFormat(response);

			// Extract JSON from the response text
			const jsonText = extractJson(result.text);

			// Parse and validate JSON
			let parsedObject;
			try {
				parsedObject = JSON.parse(jsonText);
			} catch (parseError) {
				throw new MCPError(
					`Failed to parse JSON response: ${parseError.message}. Response: ${result.text.substring(0, 200)}...`
				);
			}

			// Validate against schema
			try {
				const validatedObject = schema.parse(parsedObject);

				return {
					object: validatedObject,
					finishReason: result.finishReason || 'stop',
					usage: {
						promptTokens: result.usage?.inputTokens || 0,
						completionTokens: result.usage?.outputTokens || 0,
						totalTokens:
							(result.usage?.inputTokens || 0) +
							(result.usage?.outputTokens || 0)
					},

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Increase maxTokens / reduce schema size so the JSON is not truncated
  2. Strengthen the prompt to demand raw JSON only (no fences/commentary), or strip code fences before parsing
  3. Retry generation; if intermittent, consider a more capable model for structured output

Example fix

// before
const obj = JSON.parse(result.text);
// after
const jsonText = result.text.replace(/^```(?:json)?\n?|\n?```$/g, '').trim();
const obj = JSON.parse(jsonText);
Defensive patterns

Strategy: try-catch

Validate before calling

function isProbablyJson(text) {
  if (typeof text !== 'string' || !text.trim().startsWith('{')) return false;
  try { JSON.parse(text); return true; } catch { return false; }
}

Try / catch

try { obj = await model.doGenerateObject(opts); } catch (e) {
  if (e.message.startsWith('Failed to parse JSON response')) {
    // inspect e.message for the first 200 chars; increase maxTokens and retry
  } else throw e;
}

Prevention

When it happens

Trigger: MCP sampling response text is not valid JSON: model added markdown code fences or commentary, output was truncated by maxTokens, or the prompt/jsonInstructions did not constrain the model to JSON.

Common situations: Small/weak models ignoring JSON instructions; large schemas cut off by token limits; responses wrapped in ```json fences; empty response text.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/4a167399f0d2e2ff. Report an issue: GitHub.