apache/superset · error · DashboardNotFoundError
Dashboard not found.
Error message
Dashboard not found.
What it means
DashboardNotFoundError raised by DashboardDAO.get_by_id_or_slug(): the lookup by id-or-slug (id_or_slug_filter) plus the DAO base filter returned one_or_none() == None. As with charts, the base filter means 'not found' conflates 'does not exist' with 'not visible to you'. This variant follows the outerjoin(editors) path.
Source
Thrown at superset/daos/dashboard.py:195
@classmethod
def get_by_id_or_slug(cls, id_or_slug: int | str) -> Dashboard:
if is_uuid(id_or_slug):
# just get dashboard if it's uuid
dashboard = Dashboard.get(id_or_slug)
else:
query = (
db.session.query(Dashboard)
.filter(id_or_slug_filter(id_or_slug))
.outerjoin(Dashboard.editors)
)
# Apply dashboard base filters
query = cls.base_filter("id", SQLAInterface(Dashboard, db.session)).apply(
query, None
)
dashboard = query.one_or_none()
if not dashboard:
raise DashboardNotFoundError()
# make sure we still have basic access check from security manager
try:
dashboard.raise_for_access()
except SupersetSecurityException as ex:
raise DashboardAccessDeniedError() from ex
return dashboard
@staticmethod
def get_datasets_for_dashboard(id_or_slug: str) -> list[tuple[Any, dict[str, Any]]]:
dashboard = DashboardDAO.get_by_id_or_slug(id_or_slug)
return dashboard.datasets_trimmed_for_slices()
@staticmethod
def get_tabs_for_dashboard(id_or_slug: str) -> dict[str, Any]:
dashboard = DashboardDAO.get_by_id_or_slug(id_or_slug)
return dashboard.tabsView on GitHub (pinned to f4587218dd)
Solutions
- List dashboards as the same user (GET /api/v1/dashboard/) to confirm existence, the current slug, and visibility.
- Prefer the stable dashboard UUID over id or slug in integrations.
- Fix access: set the dashboard's ownership/roles or grant the role can-read access if the row is simply filtered out.
- Update the stored slug reference after renames.
Example fix
# before
DashboardDAO.get_by_id_or_slug("q2-sales") # slug renamed to 'sales-q2'
# after
# resolve via the API filter on the immutable uuid
GET /api/v1/dashboard/?q={"filter":[{"col":"uuid","opr":"eq","value":"<uuid>"}]} Defensive patterns
Strategy: try-catch
Validate before calling
def dashboard_exists_and_visible(id_or_slug: str) -> bool:
try:
DashboardDAO.get_by_id_or_slug(id_or_slug)
return True
except (DashboardNotFoundError, DashboardAccessDeniedError):
return False Type guard
def is_dashboard_slug(s: str) -> bool:
return isinstance(s, str) and bool(s) and not s.isdigit() # digit strings are ids Try / catch
try:
dash = DashboardDAO.get_by_id_or_slug(id_or_slug)
except DashboardNotFoundError:
abort(404)
except DashboardAccessDeniedError:
abort(403) Prevention
- Prefer UUIDs over mutable slugs in bookmarks and integrations.
- After a dashboard rename, update stored slug references.
- Check access as the end user (or guest token) before rendering links.
When it happens
Trigger: GET /api/v1/dashboard/<id-or-slug> where the dashboard was deleted, the slug changed (slug is mutable via json metadata), or the current user lacks read access; malformed id/slug string.
Common situations: Hardcoded dashboard slugs that break when someone edits the dashboard title/slug; stale ids after environment re-imports; embedded-SDK integrations referencing a dashboard the service account can't see.
Related errors
- Chart not found.
- Dashboard %(dashboard_id)s not found
- CSS template not found.
- Dashboard parameters are invalid.
- Dashboard not found.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/f75f19ff84ded36c.
Report an issue: GitHub.