{"record":{"id":"7398de635f57848b","repo":"google-gemini/gemini-cli","slug":"agent-with-name-name-is-already-loaded","errorCode":null,"errorMessage":"Agent with name '${name}' is already loaded.","messagePattern":"Agent with name '(.+?)' is already loaded\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/a2a-client-manager.ts","lineNumber":93,"sourceCode":"\n    this.a2aFetch = (input, init) =>\n      fetch(input, { ...init, dispatcher: this.a2aDispatcher } as RequestInit);\n  }\n\n  /**\n   * Loads an agent by fetching its AgentCard and caches the client.\n   * @param name The name to assign to the agent.\n   * @param agentCardUrl The full URL to the agent's card.\n   * @param authHandler Optional authentication handler to use for this agent.\n   * @returns The loaded AgentCard.\n   */\n  async loadAgent(\n    name: string,\n    options: AgentCardLoadOptions,\n    authHandler?: AuthenticationHandler,\n  ): Promise<AgentCard> {\n    if (this.clients.has(name) && this.agentCards.has(name)) {\n      throw new Error(`Agent with name '${name}' is already loaded.`);\n    }\n\n    // Authenticated fetch for API calls (transports).\n    let authFetch: typeof fetch = this.a2aFetch;\n    if (authHandler) {\n      authFetch = createAuthenticatingFetchWithRetry(\n        this.a2aFetch,\n        authHandler,\n      );\n    }\n\n    // Use unauthenticated fetch for the agent card unless explicitly required.\n    // Some servers reject unexpected auth headers on the card endpoint (e.g. 400).\n    const cardFetch = async (\n      input: RequestInfo | URL,\n      init?: RequestInit,\n    ): Promise<Response> => {\n      // Try without auth first","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/a2a-client-manager.ts#L75-L111","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Guard the call: `if (!manager.getAgentCard(name)) await manager.loadAgent(name, ...)`.","If re-registration is intentional, expose and call a removal/replace path first (or clear the maps) before re-loading.","Use distinct names for distinct agent URLs.","Make loadAgent idempotent at the caller by tracking which names have been loaded in a Set."],"exampleFix":"// before\nawait manager.loadAgent('reviewer', { url });\nawait manager.loadAgent('reviewer', { url }); // throws\n\n// after\nif (!manager.getAgentCard('reviewer')) {\n  await manager.loadAgent('reviewer', { url });\n}","handlingStrategy":"validation","validationCode":"async function loadOnce(\n  manager: A2AClientManager,\n  name: string,\n  opts: AgentCardLoadOptions,\n  auth?: AuthenticationHandler,\n) {\n  if (manager.getAgentCard(name)) return manager.getAgentCard(name)!;\n  return manager.loadAgent(name, opts, auth);\n}\n\nawait loadOnce(manager, 'reviewer', { url });","typeGuard":"function isAgentLoaded(manager: { getAgentCard(n: string): unknown }, name: string): boolean {\n  return manager.getAgentCard(name) !== undefined;\n}","tryCatchPattern":"try {\n  await manager.loadAgent(name, opts);\n} catch (e) {\n  if (e instanceof Error && e.message.endsWith('is already loaded.')) {\n    return manager.getAgentCard(name); // idempotent\n  }\n  throw e;\n}","preventionTips":["Track loaded names in a Set at the orchestration layer.","Make loadAgent idempotent in your wrapper by checking getAgentCard first.","On config hot-reload, diff the new set against the loaded set rather than re-loading all."],"tags":["a2a","agent-loading","validation","naming"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}