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
- Reconnect the account: run the provider's OAuth login flow again so a fresh access token is stored
- If it recurs, inspect the stored credential row (dev only) to see whether access_token is null and why
- 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
- After any credential migration, verify OAuth2 rows still carry an access token
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
- Picker tokens are only available for OAuth2 credentials
- Credential does not grant any scope eligible for the picker.
- Provider-runtime credentials cannot be created directly
- Server did not return an access token for the Google Drive p
- OAuth2 callback failed to exchange code for tokens: {str(e)}
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/2f0490664cc89b03.
Report an issue: GitHub.