apache/superset · error · DashboardUpdateFailedError
Dashboard not found
Error message
Dashboard not found
What it means
DashboardUpdateFailedError('Dashboard not found') raised by DashboardDAO.update_native_filters_config when called with dashboard=None (the function's guard for a missing dashboard argument). It is a control-flow guard inside native-filter reordering/deletion handling, not a query result — the caller passed no dashboard object.
Source
Thrown at superset/daos/dashboard.py:569
native_filter_configuration = metadata.get("native_filter_configuration", [])
tab_filters = defaultdict(list)
for filter in native_filter_configuration:
if tabs_in_scope := filter.get("tabsInScope", []):
for tab_key in tabs_in_scope:
tab_filters[tab_key].append(filter)
tab_filters["all"].append(filter)
return tab_filters
@classmethod
def update_native_filters_config(
cls,
dashboard: Dashboard | None = None,
attributes: dict[str, Any] | None = None,
) -> list[dict[str, Any]]:
if not dashboard:
raise DashboardUpdateFailedError("Dashboard not found")
if attributes:
try:
_parsed = json.loads(dashboard.json_metadata or "{}")
except (json.JSONDecodeError, TypeError):
_parsed = {}
metadata = _parsed if isinstance(_parsed, dict) else {}
native_filter_configuration = metadata.get(
"native_filter_configuration", []
)
reordered_filter_ids: list[int] = attributes.get("reordered", [])
deleted_ids = set(attributes.get("deleted", []))
modified_map = {f.get("id"): f for f in attributes.get("modified", [])}
updated_configuration = []
# Modify / Delete existing filters
for conf in native_filter_configuration:
conf_id = conf.get("id")View on GitHub (pinned to f4587218dd)
Solutions
- Resolve the Dashboard first: dash = DashboardDAO.get_by_id_or_slug(id_or_slug), handling its NotFound/AccessDenied errors, then pass it in.
- Do not forward None from upstream callers — fail at the fetch site.
- Catch DashboardUpdateFailedError in the API layer and map it to 404 for the client.
Example fix
# before
DashboardDAO.update_native_filters_config(None, {"reordered": [2, 1]})
# after
dash = DashboardDAO.get_by_id_or_slug(id_or_slug) # raises its own errors if absent
DashboardDAO.update_native_filters_config(dash, {"reordered": [2, 1]}) Defensive patterns
Strategy: type-guard
Validate before calling
def has_dashboard_arg(dashboard) -> bool:
return dashboard is not None Type guard
def is_resolved_dashboard(obj) -> bool:
from superset.models.dashboard import Dashboard
return isinstance(obj, Dashboard) and obj.id is not None Try / catch
try:
DashboardDAO.update_native_filters_config(dash, attributes)
except DashboardUpdateFailedError as ex:
if 'not found' in str(ex):
abort(404)
raise Prevention
- Never forward None dashboards into DAO write methods — resolve and fail at the fetch site.
- Map DashboardUpdateFailedError to a 404 in API handlers.
When it happens
Trigger: Internal/extension code invoking update_native_filters_config(dashboard=None, attributes={...}) — e.g. a dashboard API path where the dashboard failed to load upstream and None was forwarded instead of raising earlier.
Common situations: Custom plugins or fork code calling the DAO method directly without resolving the Dashboard first; refactors that moved dashboard fetching but kept the None default.
Related errors
- created_by_fk_or_editor only supports 'eq'; got '{c.opr}'
- Received unexpected response status (${response.status}) whi
- Dashboard %(dashboard_id)s not found
- Dashboard parameters are invalid.
- Dashboard parameters are invalid.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/b4c54f62bd5f0bdc.
Report an issue: GitHub.