google-gemini/gemini-cli · error · Error

OAuth2 authentication for agent "${this.agentName}" requires

Error message

OAuth2 authentication for agent "${this.agentName}" requires a client_id. Add client_id to the auth config in your agent definition.

What it means

OAuth2AuthProvider.authenticateInteractively requires config.client_id before it can build an OAuth flow; without it the Authorization Code + PKCE flow has no client identity. The error names the agent and points the user to the auth config in the agent definition. It fires during the interactive browser flow, after the provider has already tried cached tokens.

Source

Thrown at packages/core/src/agents/auth-provider/oauth2-provider.ts:213

      debugLogger.debug(
        `[OAuth2AuthProvider] Fetching agent card from ${this.agentCardUrl}`,
      );
      const resolver = new DefaultAgentCardResolver();
      const card = await resolver.resolve(this.agentCardUrl, '');
      this.mergeAgentCardDefaults(card);
    } catch (error) {
      debugLogger.warn(
        `[OAuth2AuthProvider] Could not fetch agent card for OAuth URL discovery: ${getErrorMessage(error)}`,
      );
    }
  }

  /**
   * Run a full OAuth 2.0 Authorization Code + PKCE flow through the browser.
   */
  private async authenticateInteractively(): Promise<OAuthToken> {
    if (!this.config.client_id) {
      throw new Error(
        `OAuth2 authentication for agent "${this.agentName}" requires a client_id. ` +
          'Add client_id to the auth config in your agent definition.',
      );
    }
    if (!this.authorizationUrl || !this.tokenUrl) {
      throw new Error(
        `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.',
      );
    }

    const flowConfig: OAuthFlowConfig = {
      clientId: this.config.client_id,
      clientSecret: this.config.client_secret,
      authorizationUrl: this.authorizationUrl,
      tokenUrl: this.tokenUrl,
      scopes: this.scopes,
    };

View on GitHub (pinned to 5024443c72)

Solutions

  1. Add client_id to the auth block in the agent frontmatter.
  2. Register an OAuth client with the provider and copy the issued client_id.
  3. Use the snake_case key 'client_id' (not clientId) to match the schema.
  4. If the server supports a different auth scheme, switch to one that does not need a client_id.

Example fix

# before
auth:
  type: oauth
  client_secret: secret

# after
auth:
  type: oauth
  client_id: my-registered-client-id
  client_secret: secret
Defensive patterns

Strategy: validation

Validate before calling

if (authConfig.type === 'oauth2' && !authConfig.client_id) {
  throw new Error('oauth2 auth requires a client_id in the agent definition.');
}
await A2AAuthProviderFactory.create({ authConfig, agentName });

Type guard

function hasClientId(c: { client_id?: string }): c is { client_id: string } {
  return typeof c.client_id === 'string' && c.client_id.length > 0;
}

Prevention

When it happens

Trigger: An agent whose auth.type is 'oauth' (mapped to oauth2) but the frontmatter omits client_id; client_id set to an empty string; the field renamed in an edit; an auto-generated config missing the field.

Common situations: Copy-pasting an oauth example without the client_id; expecting the agent card to supply client_id (the card supplies URLs but not the client_id, which is the integrator's own app registration); a typo in the key (e.g. clientId camelCase).

Understand the failure class

Related errors


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