google-gemini/gemini-cli · error

[A2AClientManager] sendMessageStream Error [${agentName}]: $

Error message

[A2AClientManager] sendMessageStream Error [${agentName}]: ${error.message}

What it means

Thrown by `sendMessageStream` when the underlying A2A client's stream raises an `Error`. The manager catches it, prefixes it with the agent name and method for traceability, and re-throws a new Error that preserves the original as `cause`. This is the 'known Error shape' branch of the catch.

Source

Thrown at packages/core/src/agents/a2a-client-manager.ts:226

    const messageParams: MessageSendParams = {
      message: {
        kind: 'message',
        role: 'user',
        messageId: uuidv4(),
        parts: [{ kind: 'text', text: message }],
        contextId: options?.contextId,
        taskId: options?.taskId,
      },
    };

    try {
      yield* client.sendMessageStream(messageParams, {
        signal: options?.signal,
      });
    } catch (error: unknown) {
      const prefix = `[A2AClientManager] sendMessageStream Error [${agentName}]`;
      if (error instanceof Error) {
        throw new Error(`${prefix}: ${error.message}`, { cause: error });
      }
      throw new Error(
        `${prefix}: Unexpected error during sendMessageStream: ${String(error)}`,
      );
    }
  }

  /**
   * Retrieves a loaded agent card.
   * @param name The name of the agent.
   * @returns The agent card, or undefined if not found.
   */
  getAgentCard(name: string): AgentCard | undefined {
    return this.agentCards.get(name);
  }

  /**
   * Retrieves a loaded client.

View on GitHub (pinned to 5024443c72)

Solutions

  1. Inspect `error.cause` for the original message from the A2A client — the actionable detail is there.
  2. For transient/network errors, retry with backoff, optionally resuming via `contextId`/`taskId` from the options.
  3. If an AbortSignal was used, check whether it was aborted and either widen the timeout or stop aborting.
  4. For remote error responses, validate the message payload and the agent's health (re-fetch its AgentCard) before retrying.

Example fix

// before
try {
  for await (const r of manager.sendMessageStream('rev', msg)) {}
} catch (e) {
  console.error((e as Error).message); // loses cause
}

// after
try {
  for await (const r of manager.sendMessageStream('rev', msg)) {}
} catch (e) {
  console.error((e as Error).message, (e as Error).cause);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  for await (const r of manager.sendMessageStream(name, msg, { signal })) {}
} catch (e) {
  const cause = (e as Error).cause;
  if (cause instanceof Error && isRetryable(cause)) {
    await backoff();
    // retry with contextId to resume
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: The remote A2A agent returns an error response over the stream, the network connection drops mid-stream, the client times out, or an AbortSignal fires and the client surfaces it as an Error. Any of these land in the `error instanceof Error` branch.

Common situations: Remote agent crashed or returned an error event; transient network failure during streaming; an AbortController aborted the request; auth token expired mid-conversation; the remote agent rejected the message payload.

Related errors


AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12). Data as JSON: /api/errors/281b720e42831833. Report an issue: GitHub.