Significant-Gravitas/AutoGPT · error · HTTPException

Picker tokens are only available for OAuth2 credentials

Error message

Picker tokens are only available for OAuth2 credentials

What it means

The picker-token endpoint returns 400 'Picker tokens are only available for OAuth2 credentials' when the fetched credential is not an OAuth2Credentials instance — e.g. an APIKeyCredentials (API key/secret) was passed. Picker flows need an OAuth bearer access token, which API-key credentials do not have.

Source

Thrown at autogpt_platform/backend/backend/api/features/integrations/router.py:526

    token + its expiry — nothing else about the credential. SDK-default
    credentials are excluded for the same reason as `get_credential`.
    """
    if is_sdk_default(cred_id):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )

    credential = await creds_manager.get(user_id, cred_id)
    if not credential:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )
    if not provider_matches(credential.provider, provider):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )
    if not isinstance(credential, OAuth2Credentials):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Picker tokens are only available for OAuth2 credentials",
        )
    if not credential.access_token:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Credential has no access token; reconnect the account",
        )

    # Gate on provider+scope: only credentials that actually grant access to
    # a provider-hosted picker flow may mint a token through this endpoint.
    # Prevents using this path to extract bearer tokens for unrelated OAuth
    # integrations (e.g. GitHub) that happen to be stored under the same user.
    allowed_scopes = _PICKER_TOKEN_ALLOWED_SCOPES.get(provider)
    if not allowed_scopes:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=(f"Picker tokens are not available for provider '{provider.value}'"),

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Check the credential's type via the list endpoint ('type' field); picker-token requires 'oauth2'
  2. Connect the provider through OAuth (login flow) instead of pasting an API key
  3. In UI, only enable the picker entry point when the selected credential is OAuth2
Defensive patterns

Strategy: type-guard

Validate before calling

meta = next(c for c in all_credentials if c['id'] == cred_id)
if meta['type'] != 'oauth2':
    raise TypeError('picker token requires an OAuth2 credential; connect via sign-in, not API key')

Type guard

function isOAuth2Credential(meta: { type: string }): boolean {
  return meta.type === 'oauth2';
}

Prevention

When it happens

Trigger: POST /integrations/{provider}/credentials/{api-key-cred-id}/picker-token where the stored credential is of type 'api_key' (or any non-oauth2 type).

Common situations: User connected a provider by pasting an API key where the UI expects an OAuth connection; cred_id resolved to the wrong credential of the same provider.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/0e067882b9bb24bb. Report an issue: GitHub.