Significant-Gravitas/AutoGPT · error · HTTPException

System-managed credentials cannot be deleted

Error message

System-managed credentials cannot be deleted

What it means

Raised (HTTP 403) by the external delete-credential endpoint when `is_system_credential(cred_id)` is true — the credential is system-managed (e.g. provisioned by operators for all users). Unlike unknown ids (404), this is an explicit authorization refusal: the credential exists but the external API is not allowed to remove it.

Source

Thrown at autogpt_platform/backend/backend/api/external/v1/integrations.py:634

    provider: Annotated[str, Path(title="The provider")],
    cred_id: Annotated[str, Path(title="The credential ID to delete")],
    auth: APIAuthorizationInfo = Security(
        require_permission(APIKeyPermission.DELETE_INTEGRATIONS)
    ),
) -> DeleteCredentialResponse:
    """
    Delete a credential.

    Note: This does not revoke the tokens with the provider. For full cleanup,
    use the main API's delete endpoint which handles webhook cleanup and
    token revocation.
    """
    if is_sdk_default(cred_id):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )
    if is_system_credential(cred_id):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="System-managed credentials cannot be deleted",
        )
    creds = await creds_manager.store.get_creds_by_id(auth.user_id, cred_id)
    if not creds:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )
    if not provider_matches(creds.provider, provider):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Credentials not found"
        )

    await creds_manager.delete(auth.user_id, cred_id)

    return DeleteCredentialResponse(deleted=True, credentials_id=cred_id)

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Do not delete system-managed credentials; exclude them from automated cleanup.
  2. If removal is genuinely required, ask the platform operator to unprovision it server-side.
  3. Distinguish 403 (exists, forbidden) from 404 (doesn't exist / not yours) in client error handling.
Defensive patterns

Strategy: validation

Validate before calling

SYSTEM_CRED_IDS = load_system_credential_ids()  # operator-provisioned set
if cred_id in SYSTEM_CRED_IDS:
    skip("system-managed credential; not deletable via API")

Try / catch

try:
    client.delete(f"/integrations/{provider}/credentials/{cred_id}")
except HTTPError as e:
    if e.response.status_code == 403 and "System-managed" in e.response.text:
        log("skip system credential", cred_id)  # expected; requires operator action
    else:
        raise

Prevention

When it happens

Trigger: DELETE `/integrations/{provider}/credentials/{cred_id}` targeting a system-managed credential id.

Common situations: Shared operator-provisioned credentials appearing in a user's integration list; automated cleanup sweeps that iterate all visible credentials.

Related errors


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