{"record":{"id":"12cf904211e8ac8d","repo":"google-gemini/gemini-cli","slug":"oauth2-authentication-for-agent-this-agentname-12cf90","errorCode":null,"errorMessage":"OAuth2 authentication for agent \"${this.agentName}\" requires authorization_url and token_url. Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme.","messagePattern":"OAuth2 authentication for agent \"(.+?)\" requires authorization_url and token_url\\. Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/auth-provider/oauth2-provider.ts","lineNumber":219,"sourceCode":"    } catch (error) {\n      debugLogger.warn(\n        `[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`,\n      );\n    }\n  }\n\n  /**\n   * Run a full OAuth 2.0 Authorization Code + PKCE flow through the browser.\n   */\n  private async authenticateInteractively(): Promise<OAuthToken> {\n    if (!this.config.client_id) {\n      throw new Error(\n        `OAuth2 authentication for agent \"${this.agentName}\" requires a client_id. ` +\n          'Add client_id to the auth config in your agent definition.',\n      );\n    }\n    if (!this.authorizationUrl || !this.tokenUrl) {\n      throw new Error(\n        `OAuth2 authentication for agent \"${this.agentName}\" requires authorization_url and token_url. ` +\n          'Provide them in the auth config or ensure the agent card exposes an oauth2 security scheme.',\n      );\n    }\n\n    const flowConfig: OAuthFlowConfig = {\n      clientId: this.config.client_id,\n      clientSecret: this.config.client_secret,\n      authorizationUrl: this.authorizationUrl,\n      tokenUrl: this.tokenUrl,\n      scopes: this.scopes,\n    };\n\n    const pkceParams = generatePKCEParams();\n    const preferredPort = getPortFromUrl(flowConfig.redirectUri);\n    const callbackServer = startCallbackServer(pkceParams.state, preferredPort);\n    const redirectPort = await callbackServer.port;\n","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/auth-provider/oauth2-provider.ts#L201-L237","documentation":"The OAuth2 flow needs authorization_url and token_url. The provider tries to discover them from the agent card's oauth2 security scheme (fetchAgentCardDefaults/mergeAgentCardDefaults) and falls back to config values. If neither source yields both URLs, authenticateInteractively refuses to start. The error tells the user to supply them or ensure the card exposes the scheme.","triggerScenarios":"Agent card unreachable so fetchAgentCardDefaults warned and skipped; the card has no securitySchemes or none of type oauth2; config omits authorization_url/token_url; the card was fetched but the scheme names differ from what the merger expects.","commonSituations":"agent_card_url behind a firewall during discovery; a server whose card uses a non-standard security scheme key; local-only testing where the card endpoint is not served; config edited to remove the URLs assuming the card would supply them.","solutions":["Add authorization_url and token_url to the auth config in the frontmatter.","Ensure the agent card exposes an oauth2 security scheme with the correct flow URLs.","Confirm agent_card_url is reachable from the runtime so discovery can populate the URLs.","Check fetchAgentCardDefaults warnings in debug logs for discovery failures."],"exampleFix":"# before - expecting card to supply URLs but it did not\nauth:\n  type: oauth\n  client_id: my-id\n\n# after\nauth:\n  type: oauth\n  client_id: my-id\n  authorization_url: https://auth.example/authorize\n  token_url: https://auth.example/token","handlingStrategy":"validation","validationCode":"if (authConfig.type === 'oauth2'\n    && (!authConfig.authorization_url || !authConfig.token_url)) {\n  throw new Error('oauth2 requires authorization_url and token_url (or an agent card that exposes them).');\n}\nawait A2AAuthProviderFactory.create({ authConfig, agentName, agentCardUrl });","typeGuard":"function hasOAuthUrls(c: { authorization_url?: string; token_url?: string }): boolean {\n  return typeof c.authorization_url === 'string' && typeof c.token_url === 'string';\n}","tryCatchPattern":null,"preventionTips":["Supply authorization_url and token_url in frontmatter when the card cannot be discovered.","Ensure agent_card_url is reachable so the provider can auto-discover them.","Check debug logs for fetchAgentCardDefaults warnings."],"tags":["auth","oauth2","config","discovery"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}