apache/superset · error · DatabaseNotFoundError
Database not found
Error message
Database not found
What it means
DatabaseNotFoundError('Database not found') raised at oauth2.py:123 in OAuth2StoreTokenCommand.validate: the state parameter decoded fine and carries a database_id, but DatabaseUserOAuth2TokensDAO.get_database(state['database_id']) returns no Database row. The database that initiated the OAuth2 flow no longer exists (or the state was crafted with a bogus id).
Source
Thrown at superset/commands/database/oauth2.py:123
"database_id": self._state["database_id"],
"access_token": token_response["access_token"],
"access_token_expiration": expiration,
"refresh_token": token_response.get("refresh_token"),
},
)
def validate(self) -> None:
if error := self._parameters.get("error"):
raise OAuth2Error(error)
self._state = decode_oauth2_state(self._parameters["state"])
if database := DatabaseUserOAuth2TokensDAO.get_database(
self._state["database_id"]
):
self._database = database
else:
raise DatabaseNotFoundError("Database not found")
View on GitHub (pinned to f4587218dd)
Solutions
- Confirm the database still exists: GET /api/v1/database/ and re-initiate the connection flow from SQL Lab for the (new) database.
- Never bookmark or replay OAuth2 callback URLs — always start from the connection dialog.
- If the database was re-created, note it has a new id; the old state will never resolve.
Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.database import DatabaseUserOAuth2TokensDAO
from superset.utils.oauth2 import decode_oauth2_state
def state_references_live_database(state_jwt: str) -> bool:
state = decode_oauth2_state(state_jwt)
return DatabaseUserOAuth2TokensDAO.get_database(state["database_id"]) is not None Try / catch
from superset.commands.database.exceptions import DatabaseNotFoundError
try:
OAuth2StoreTokenCommand(params).run()
except DatabaseNotFoundError:
# the initiating database was deleted mid-flow: restart from a live database
refresh_database_list() Prevention
- Never bookmark or replay OAuth2 callback URLs; always start from the connection dialog of a live database.
- Coordinate database decommissioning with in-flight user sessions.
- After a database is re-created it has a new id — old state strings will never resolve.
When it happens
Trigger: GET /oauth2/authorize completing a flow whose database was deleted between the authorize redirect and the callback; a state JWT signed with a stale/foreign database_id; the database hard-deleted by an admin mid-flow.
Common situations: Admin decommissions a database while a user sits on the provider consent screen; environments where state strings are reused/bookmarked; database deleted and re-created with a new id.
Related errors
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/ea627949b70bdd21.
Report an issue: GitHub.