mastra-ai/mastra · error · MastraClientErrorClass

A2A JSON-RPC response did not include a result

Error message

A2A JSON-RPC response did not include a result

What it means

A2A JSON-RPC responses must carry either a `result` (success) or an `error`. unwrapA2AResult throws a MastraClientError when a 200 response contains neither — the server returned a malformed JSON-RPC payload, so the client refuses to return undefined to callers.

Source

Thrown at client-sdks/client-js/src/resources/a2a.ts:88

function createA2AJsonRpcError(response: JSONRPCErrorResponse): Error {
  const error = response.error;
  const message = error?.message ?? 'Unknown A2A JSON-RPC error';
  return typeof error?.code === 'number'
    ? new MastraA2AError(error.code, message, error.data)
    : new MastraClientErrorClass(200, 'OK', `A2A JSON-RPC error - ${message}`, error);
}

function unwrapA2AResult<TResult>(response: JSONRPCResponse): TResult {
  if ('error' in response && response.error) {
    throw createA2AJsonRpcError(response as JSONRPCErrorResponse);
  }

  if ('result' in response) {
    return response.result as TResult;
  }

  throw new MastraClientErrorClass(200, 'OK', 'A2A JSON-RPC response did not include a result', response);
}

async function requireResponseBody(response: Response, method: string): Promise<ReadableStream<Uint8Array>> {
  if (response.body) {
    return response.body;
  }

  const headerSummary = Array.from(response.headers.entries())
    .map(([key, value]) => `${key}: ${value}`)
    .join(', ');

  let responseText = '';
  try {
    responseText = await response.text();
  } catch {
    // Ignore body read failures and surface the rest of the response context.
  }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Log response.error — the MastraClientError includes the full response payload; check for a JSON-RPC error object the client didn't map.
  2. Verify the A2A server URL points at a compliant A2A JSON-RPC endpoint.
  3. Upgrade/align client and server versions so the JSON-RPC envelope matches.
  4. Inspect any proxy/gateway that could rewrite the response body.
Defensive patterns

Strategy: try-catch

Type guard

function isJsonRpcSuccess<T>(r: unknown): r is { result: T } {
  return typeof r === 'object' && r !== null && 'result' in r;
}

Try / catch

try {
  const card = await a2a.getExtendedAgentCard();
} catch (e) {
  if (e instanceof MastraClientError && e.message.includes('did not include a result')) {
    // inspect e.response for a JSON-RPC error object or non-JSON-RPC payload
  }
  throw e;
}

Prevention

When it happens

Trigger: Any A2A RPC call (rpc, getExtendedAgentCard, task push-notification config get/set/list/delete) where the server responds 200 with JSON lacking both 'result' and a handled 'error' field — e.g. an A2A server bug, a non-JSON-RPC proxy response, or an error payload shape the client doesn't recognize.

Common situations: Pointing the A2A client at an endpoint that isn't a compliant A2A server (HTML error page behind a 200, gateway response); version mismatch between client and server JSON-RPC envelope.

Related errors


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