apache/superset · error · DatabaseNotFoundError
Database not found.
Error message
Database not found.
What it means
DatabaseNotFoundError raised in DeleteDatabaseCommand.validate (delete.py:54) when DatabaseDAO.find_by_id(self._model_id) returns nothing. The database id targeted by DELETE /api/v1/database/<id> does not exist in the metadata DB.
Source
Thrown at superset/commands/database/delete.py:54
logger = logging.getLogger(__name__)
class DeleteDatabaseCommand(BaseCommand):
def __init__(self, model_id: int):
self._model_id = model_id
self._model: Optional[Database] = None
@transaction(on_error=partial(on_error, reraise=DatabaseDeleteFailedError))
def run(self) -> None:
self.validate()
assert self._model
DatabaseDAO.delete([self._model])
def validate(self) -> None:
# Validate/populate model exists
self._model = DatabaseDAO.find_by_id(self._model_id)
if not self._model:
raise DatabaseNotFoundError()
# Check there are no associated ReportSchedules
if reports := ReportScheduleDAO.find_by_database_id(self._model_id):
report_names = [report.name for report in reports]
raise DatabaseDeleteFailedReportsExistError(
_(
"There are associated alerts or reports: %(report_names)s",
report_names=",".join(report_names),
)
)
# Check if there are datasets for this database. ``self._model.tables``
# would now hide soft-deleted datasets (``SqlaTable`` inherits
# ``SoftDeleteMixin``, so the relationship lazy-load applies the
# visibility filter), letting a database whose datasets are all
# soft-deleted look empty and be hard-deleted while ``tables.database_id``
# rows still reference it. Count with the visibility filter bypassed so
# soft-deleted datasets still block the delete.
from superset.connectors.sqla.models import ( # pylint: disable=import-outside-toplevelView on GitHub (pinned to f4587218dd)
Solutions
- List databases (GET /api/v1/database/) and confirm the id before deleting.
- Treat 404 as success in idempotent automation (the end state you wanted is already reached).
- Refresh cached ids after exports/imports or environment resets.
Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.database import DatabaseDAO
def database_exists(model_id: int) -> bool:
return DatabaseDAO.find_by_id(model_id) is not None Try / catch
from superset.commands.database.exceptions import DatabaseNotFoundError
try:
DeleteDatabaseCommand(model_id).run()
except DatabaseNotFoundError:
pass # already gone: treat delete as idempotent success Prevention
- Make deletion scripts idempotent: treat 404 as the desired end state.
- Re-check the id via GET /api/v1/database/ before deleting in automation.
When it happens
Trigger: DELETE /api/v1/database/<id> with an id that was already deleted, never existed, or came from another environment.
Common situations: Double-delete races (two admins, or UI plus script); scripts with cached ids after environment rebuild; typos in the id.
Related errors
- Chart not found.
- CSS template not found.
- Dashboard not found.
- Dashboard not found.
- There are associated alerts or reports: %(report_names)s
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/4922ab8cdbad6eed.
Report an issue: GitHub.