Significant-Gravitas/AutoGPT · error · HTTPException

Credential has no access token; reconnect the account

Error message

Credential has no access token; reconnect the account

What it means

The picker-token endpoint returns 400 'Credential has no access token; reconnect the account' when the OAuth2 credential exists but its access_token is empty. This can happen for provider_runtime-refresh credentials or corrupted/stripped records where no usable bearer token is stored.

Source

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

            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}'"),
        )
    cred_scopes = set(credential.scopes or [])
    if cred_scopes.isdisjoint(allowed_scopes):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Reconnect the account: run the provider's OAuth login flow again so a fresh access token is stored
  2. If it recurs, inspect the stored credential row (dev only) to see whether access_token is null and why
  3. Delete the broken credential and re-create it via the normal connect flow
Defensive patterns

Strategy: retry

Try / catch

if resp.status_code == 400 and 'reconnect' in resp.json()['detail']:
    await start_oauth_login(provider)  # refresh credential, then retry once
else:
    resp.raise_for_status()

Prevention

When it happens

Trigger: POST picker-token against an OAuth2 credential whose access_token is None/empty (e.g. a provider-runtime credential that only materializes tokens at call time, or a record written without a token).

Common situations: Credential created through a non-standard path that skipped storing the access token; token was dropped during a migration or manual DB edit; provider_runtime strategy credentials (which the create endpoint now blocks) already in the store.

Related errors


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