Significant-Gravitas/AutoGPT · error · HTTPException
System credentials cannot be upgraded
Error message
System credentials cannot be upgraded
What it means
Raised by _prepare_scope_upgrade when initiating an OAuth scope upgrade for a credential ID that is a platform-owned system credential (is_system_credential(credential_id) is true). System credentials are shared across all users, so letting any user's upgrade flow change their scopes would leak/alter access for everyone. HTTP 400 'System credentials cannot be upgraded'.
Source
Thrown at autogpt_platform/backend/backend/api/features/integrations/router.py:968
async def _prepare_scope_upgrade(
user_id: str,
provider: ProviderName,
credential_id: str,
requested_scopes: list[str],
) -> list[str]:
"""Validate an existing credential for scope upgrade and compute scopes.
For providers without native incremental auth (e.g. GitHub), returns the
union of existing + requested scopes. For providers that handle merging
server-side (e.g. Google with ``include_granted_scopes``), returns the
requested scopes unchanged.
Raises HTTPException on validation failure.
"""
# Platform-owned system credentials must never be upgraded — scope
# changes here would leak across every user that shares them.
if is_system_credential(credential_id):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="System credentials cannot be upgraded",
)
existing = await creds_manager.store.get_creds_by_id(user_id, credential_id)
if not existing:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Credential to upgrade not found",
)
if not isinstance(existing, OAuth2Credentials):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Only OAuth2 credentials can be upgraded",
)
if not provider_matches(existing.provider, provider.value):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,View on GitHub (pinned to 9c8bb5550f)
Solutions
- Do not target system credentials for upgrade — they are provisioned and rotated by platform operators only.
- Filter the credential list before offering upgrade: exclude IDs where is_system_credential(id) is true (they are identifiable by their ID prefix/format).
- If broader scopes on a system credential are genuinely needed, request it from the platform operators rather than via the API.
- Create a personal (user-owned) credential for the provider and upgrade that instead.
Example fix
# before
upgrade_target = next(c for c in my_credentials if c.provider == provider)
# after: exclude system credentials from upgrade candidates
upgrade_target = next(
c for c in my_credentials
if c.provider == provider and not is_system_credential(c.id)
) Defensive patterns
Strategy: type-guard
Type guard
# Exclude system credentials before initiating an upgrade
def is_upgradable(cred) -> bool:
return cred["type"] == "oauth2" and not is_system_credential(cred["id"]) and not cred.get("is_managed") Prevention
- Filter system credentials out of any credential picker used for scope upgrades.
- Treat system credentials as read-only platform resources.
- Unit-test the credential picker against a fixture containing a system credential.
When it happens
Trigger: Calling the OAuth login/upgrade flow (GET /integrations/{provider}/login with an upgrade target) while passing the ID of a system credential — e.g. one provisioned by the platform for managed blocks; frontend state holding a system credential ID from a provider dropdown and submitting it as the upgrade target.
Common situations: UI bug where the credential picker includes system credentials in the upgrade list; scripts that iterate all credentials and try upgrading each; misunderstanding that managed/system connections are read-only for users.
Related errors
- Only OAuth2 credentials can be upgraded
- Credential provider does not match the requested provider
- Managed credentials cannot be upgraded
- Username mismatch: authenticated as a different user
- Server did not return an access token for the Google Drive p
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/d989fc5d3df8b8d0.
Report an issue: GitHub.