mastra-ai/mastra · error

Failed to parse A2A stream event: ${error instanceof Error ?

Error message

Failed to parse A2A stream event: ${error instanceof Error ? error.message : 'unknown parse error'}

What it means

parseEventBlock in the A2A (Agent-to-Agent) stream processor expects each event payload line to be valid JSON. When JSON.parse fails, the client wraps the underlying parse error in this Error so developers know which streamed event could not be decoded.

Source

Thrown at client-sdks/client-js/src/utils/process-a2a-stream.ts:43

  if (!trimmedBlock) {
    return {};
  }

  const lines = trimmedBlock.split(/\r?\n/);
  const dataLines = lines.filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart());

  const payload = dataLines.length > 0 ? dataLines.join('\n') : trimmedBlock;

  if (!payload || payload === '[DONE]') {
    return { done: true };
  }

  let parsed: unknown;
  try {
    parsed = JSON.parse(payload);
  } catch (error) {
    throw new Error(
      `Failed to parse A2A stream event: ${error instanceof Error ? error.message : 'unknown parse error'}`,
    );
  }

  if (parsed && typeof parsed === 'object' && 'error' in parsed && parsed.error) {
    throw new MastraClientError(200, 'OK', `A2A stream error - ${JSON.stringify(parsed.error)}`, parsed.error);
  }

  if (parsed && typeof parsed === 'object' && 'result' in parsed) {
    return { event: parsed.result as T };
  }

  return { event: parsed as T };
}

export async function* processA2AStream<T = A2AStreamEventData>(
  stream: globalThis.ReadableStream<Uint8Array>,
): AsyncGenerator<T, void, undefined> {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Log the raw payload line that failed to parse to see whether it is truncated, HTML, or concatenated JSON.
  2. Ensure the A2A server emits newline-delimited, individually valid JSON objects with proper framing.
  3. Check proxies/load balancers for response buffering or modification of the streaming response (disable buffering, fix error pages injected mid-stream).
  4. Verify network stability / retry the stream on disconnect to avoid truncated final events.
  5. Upgrade both @mastra/client-js and the A2A server package to compatible versions.

Example fix

// before (server)
res.write(JSON.stringify(event) + JSON.stringify(next)); // concatenated
// after (server)
res.write(JSON.stringify(event) + '\n');
res.write(JSON.stringify(next) + '\n');
Defensive patterns

Strategy: try-catch

Validate before calling

// validate each SSE data line before trusting it
function isPlausibleJsonLine(line: string): boolean {
  const t = line.trim();
  return t.startsWith('{') && t.endsWith('}') || t.startsWith('[') && t.endsWith(']');
}

Type guard

function isParsedA2AEvent(v: unknown): v is Record<string, unknown> {
  try { JSON.parse(typeof v === 'string' ? v : JSON.stringify(v)); return typeof v === 'object' && v !== null; }
  catch { return false; }
}

Try / catch

try {
  for await (const event of a2aStream) handle(event);
} catch (e) {
  if (e.message.startsWith('Failed to parse A2A stream event')) {
    console.error('Malformed event from A2A server:', e.message);
    // reconnect and resume stream, or log raw payload for server-side debugging
  } else throw e;
}

Prevention

When it happens

Trigger: Consuming an A2A stream via the client where a data/event block contains malformed JSON — e.g. truncated lines from a broken connection, non-JSON output (HTML error page, plain text) served with a 200, or a custom server emitting improperly serialized events.

Common situations: A2A server behind a proxy that intercepts the stream and returns an HTML error page, partial writes when the connection drops mid-event, writing multiple JSON objects without proper newlines so blocks concatenate, or custom A2A agent implementations serializing with the wrong content/encoding.

Understand the failure class

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/3559b45cfb40511d. Report an issue: GitHub.