{"record":{"id":"15125ba75501c14e","repo":"Significant-Gravitas/AutoGPT","slug":"credential-provider-does-not-match-the-requested-p","errorCode":null,"errorMessage":"Credential provider does not match the requested provider","messagePattern":"Credential provider does not match the requested provider","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"autogpt_platform/backend/backend/api/features/integrations/router.py","lineNumber":985,"sourceCode":"    if is_system_credential(credential_id):\n        raise HTTPException(\n            status_code=status.HTTP_400_BAD_REQUEST,\n            detail=\"System credentials cannot be upgraded\",\n        )\n\n    existing = await creds_manager.store.get_creds_by_id(user_id, credential_id)\n    if not existing:\n        raise HTTPException(\n            status_code=status.HTTP_404_NOT_FOUND,\n            detail=\"Credential to upgrade not found\",\n        )\n    if not isinstance(existing, OAuth2Credentials):\n        raise HTTPException(\n            status_code=status.HTTP_400_BAD_REQUEST,\n            detail=\"Only OAuth2 credentials can be upgraded\",\n        )\n    if not provider_matches(existing.provider, provider.value):\n        raise HTTPException(\n            status_code=status.HTTP_400_BAD_REQUEST,\n            detail=\"Credential provider does not match the requested provider\",\n        )\n    if existing.is_managed:\n        raise HTTPException(\n            status_code=status.HTTP_400_BAD_REQUEST,\n            detail=\"Managed credentials cannot be upgraded\",\n        )\n\n    # Google handles scope merging via include_granted_scopes; others need\n    # the union of existing + new scopes in the login URL.\n    if provider != ProviderName.GOOGLE:\n        requested_scopes = list(set(requested_scopes) | set(existing.scopes))\n\n    return requested_scopes\n\n\nasync def _merge_or_create_credential(","sourceCodeStart":967,"sourceCodeEnd":1003,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/integrations/router.py#L967-L1003","documentation":"In _prepare_scope_upgrade, provider_matches(existing.provider, provider.value) compares the credential's stored provider with the provider in the upgrade request URL. If they differ (e.g. upgrading via /integrations/github/login while the credential belongs to 'todoist'), HTTP 400 'Credential provider does not match the requested provider' is raised. This prevents cross-provider scope injection — merging scopes obtained from one provider's consent into another provider's credential.","triggerScenarios":"Frontend sends the upgrade request to the wrong provider route after the user switched provider in the credential dialog; ID mix-up where a credential from provider A is submitted with provider B's login URL; aliased provider names that don't match the stored value.","commonSituations":"UI state bug: provider selector changed but the credential_id state retained from the previous provider; copy-pasted request templates with the wrong provider segment; providers renamed between versions so stored provider values differ from current enum values.","solutions":["Ensure the provider segment of the upgrade/login URL equals the credential's provider field (compare provider_matches-compatible values).","Re-fetch the credential and read its provider before building the request.","If the provider was renamed in an upgrade, migrate stored credentials to the new provider value."],"exampleFix":"# before\nresp = client.get(f\"/integrations/{selected_provider}/login\", params={\"upgrade_credentials_id\": cred.id})\n\n# after: derive provider from the credential itself\nresp = client.get(f\"/integrations/{cred.provider}/login\", params={\"upgrade_credentials_id\": cred.id})","handlingStrategy":"validation","validationCode":"# Derive the route provider from the credential record itself\ncred = await fetch_credential(credential_id)\nassert provider_matches(cred[\"provider\"], provider), \"cross-provider upgrade request\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never let a provider selector and a credential_id travel independently through UI state.","Build OAuth URLs from the credential's own provider field."],"tags":["oauth","credentials","http-400","provider-mismatch"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}