google-gemini/gemini-cli · error

Agent with name '${name}' is already loaded.

Error message

Agent with name '${name}' is already loaded.

What it means

Thrown by `A2AClientManager.loadAgent` when both `clients` and `agentCards` maps already contain an entry under the requested `name`. The manager treats name as a unique handle for a loaded remote agent and refuses to silently overwrite an existing client/card, since doing so could swap the auth handler and AgentCard a caller is relying on.

Source

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

    this.a2aFetch = (input, init) =>
      fetch(input, { ...init, dispatcher: this.a2aDispatcher } as RequestInit);
  }

  /**
   * Loads an agent by fetching its AgentCard and caches the client.
   * @param name The name to assign to the agent.
   * @param agentCardUrl The full URL to the agent's card.
   * @param authHandler Optional authentication handler to use for this agent.
   * @returns The loaded AgentCard.
   */
  async loadAgent(
    name: string,
    options: AgentCardLoadOptions,
    authHandler?: AuthenticationHandler,
  ): Promise<AgentCard> {
    if (this.clients.has(name) && this.agentCards.has(name)) {
      throw new Error(`Agent with name '${name}' is already loaded.`);
    }

    // Authenticated fetch for API calls (transports).
    let authFetch: typeof fetch = this.a2aFetch;
    if (authHandler) {
      authFetch = createAuthenticatingFetchWithRetry(
        this.a2aFetch,
        authHandler,
      );
    }

    // Use unauthenticated fetch for the agent card unless explicitly required.
    // Some servers reject unexpected auth headers on the card endpoint (e.g. 400).
    const cardFetch = async (
      input: RequestInfo | URL,
      init?: RequestInit,
    ): Promise<Response> => {
      // Try without auth first

View on GitHub (pinned to 5024443c72)

Solutions

  1. Guard the call: `if (!manager.getAgentCard(name)) await manager.loadAgent(name, ...)`.
  2. If re-registration is intentional, expose and call a removal/replace path first (or clear the maps) before re-loading.
  3. Use distinct names for distinct agent URLs.
  4. Make loadAgent idempotent at the caller by tracking which names have been loaded in a Set.

Example fix

// before
await manager.loadAgent('reviewer', { url });
await manager.loadAgent('reviewer', { url }); // throws

// after
if (!manager.getAgentCard('reviewer')) {
  await manager.loadAgent('reviewer', { url });
}
Defensive patterns

Strategy: validation

Validate before calling

async function loadOnce(
  manager: A2AClientManager,
  name: string,
  opts: AgentCardLoadOptions,
  auth?: AuthenticationHandler,
) {
  if (manager.getAgentCard(name)) return manager.getAgentCard(name)!;
  return manager.loadAgent(name, opts, auth);
}

await loadOnce(manager, 'reviewer', { url });

Type guard

function isAgentLoaded(manager: { getAgentCard(n: string): unknown }, name: string): boolean {
  return manager.getAgentCard(name) !== undefined;
}

Try / catch

try {
  await manager.loadAgent(name, opts);
} catch (e) {
  if (e instanceof Error && e.message.endsWith('is already loaded.')) {
    return manager.getAgentCard(name); // idempotent
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `loadAgent('reviewer', ...)` twice without first removing the prior 'reviewer' entry; loading two different agent URLs under the same logical name; a startup routine that re-invokes loadAgent on every request without checking `getAgentCard(name)` first.

Common situations: A config loader that re-runs on hot-reload and re-registers every agent; two modules independently loading the same remote agent under a shared alias; a retry loop that calls loadAgent again after a partial success.

Related errors


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