{"record":{"id":"2afd3e874474e1e5","repo":"apache/superset","slug":"oauth2-redirect-error","errorCode":"OAUTH2_REDIRECT_ERROR","errorMessage":"Something went wrong while doing OAuth2","messagePattern":"Something went wrong while doing OAuth2","errorType":"exception","errorClass":"OAuth2Error","httpStatus":500,"severity":"error","filePath":"superset/commands/database/oauth2.py","lineNumber":57,"sourceCode":"class OAuth2StoreTokenCommand(BaseCommand):\n    \"\"\"\n    Command to store OAuth2 tokens in the database.\n    \"\"\"\n\n    def __init__(self, parameters: OAuth2ProviderResponseSchema):\n        self._parameters = parameters\n        self._state: OAuth2State | None = None\n        self._database: Database | None = None\n\n    @transaction(on_error=partial(on_error, reraise=OAuth2Error))\n    def run(self) -> DatabaseUserOAuth2Tokens:\n        self.validate()\n        self._database = cast(Database, self._database)\n        self._state = cast(OAuth2State, self._state)\n\n        oauth2_config = self._database.get_oauth2_config()\n        if oauth2_config is None:\n            raise OAuth2Error(\"No configuration found for OAuth2\")\n\n        # Look up PKCE code_verifier from KV store (RFC 7636)\n        code_verifier = None\n        tab_id = self._state[\"tab_id\"]\n        try:\n            tab_uuid = UUID(tab_id)\n        except ValueError:\n            tab_uuid = None\n\n        if tab_uuid:\n            kv_value = KeyValueDAO.get_value(\n                resource=KeyValueResource.PKCE_CODE_VERIFIER,\n                key=tab_uuid,\n                codec=JsonKeyValueCodec(),\n            )\n            if kv_value:\n                code_verifier = kv_value.get(\"code_verifier\")\n                KeyValueDAO.delete_entry(KeyValueResource.PKCE_CODE_VERIFIER, tab_uuid)","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/database/oauth2.py#L39-L75","documentation":"OAuth2Error raised at oauth2.py:57 when Database.get_oauth2_config() returns None for the database being authenticated. get_oauth2_config resolves the OAuth2 client credentials from the database's extra JSON (engine-specific OAuth2 settings); None means the engine spec supports OAuth2 but this database has no usable configuration. The class-level message ('Something went wrong while doing OAuth2') and code OAUTH2_REDIRECT_ERROR are what the API surfaces.","triggerScenarios":"Completing the OAuth2 redirect (GET /oauth2/authorize with the provider's code) for a database whose extra lacks configured OAuth2 client_id/client_secret/authorize/token URLs, or whose configured provider does not match the engine spec's expectations.","commonSituations":"Engine spec OAuth2 introduced/changed across versions (configuration key names changed); database extra JSON edited and the OAuth2 block dropped/malformed; copying a database configuration without the OAuth2 section; provider config present but for the wrong engine.","solutions":["Open the database settings (PUT /api/v1/database/<id>, extra JSON) and configure the OAuth2 block your engine spec expects — see the engine's documentation for the exact keys (client_id, client_secret, authorization_url, token_url, etc.).","Verify the engine actually supports OAuth2 in your Superset version (db_engine_spec.get_oauth2_token exists).","Re-trigger the OAuth2 flow from SQL Lab after fixing the configuration.","Check server logs for get_oauth2_config resolution details if the block looks correct."],"exampleFix":"# before: database.extra has no oauth2 block -> OAuth2Error at redirect\n# after: PUT /api/v1/database/<id>\n{\"extra\": \"{\\\"engine_params\\\": {}, \\\"metadata_params\\\": {}, \\\"oauth2_client_info\\\": {\\\"client_id\\\": \\\"...\\\", \\\"client_secret\\\": \\\"...\\\", \\\"authorize_url\\\": \\\"https://provider/oauth/authorize\\\", \\\"token_url\\\": \\\"https://provider/oauth/token\\\"}}\"}","handlingStrategy":"validation","validationCode":"db_model = DatabaseDAO.find_by_id(database_id)\nif db_model.get_oauth2_config() is None:\n    # configure the engine's OAuth2 block in extra before starting the flow\n    raise ConfigError(\"OAuth2 not configured for this database\")","typeGuard":null,"tryCatchPattern":"from superset.exceptions import OAuth2Error\n\ntry:\n    OAuth2StoreTokenCommand(params).run()\nexcept OAuth2Error as ex:\n    if \"No configuration found\" in str(ex):\n        send_admin_notice(\"configure OAuth2 for database\", database_id)","preventionTips":["Validate get_oauth2_config() before initiating the OAuth2 redirect.","Pin OAuth2 extra-JSON key names to your Superset version's engine spec when upgrading.","Smoke-test one full OAuth2 round trip after any database extra edit."],"tags":["oauth2","database","config","authentication"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}