{"record":{"id":"f75f19ff84ded36c","repo":"apache/superset","slug":"dashboard-not-found-f75f19","errorCode":null,"errorMessage":"Dashboard not found.","messagePattern":"Dashboard not found\\.","errorType":"exception","errorClass":"DashboardNotFoundError","httpStatus":404,"severity":"error","filePath":"superset/daos/dashboard.py","lineNumber":195,"sourceCode":"\n    @classmethod\n    def get_by_id_or_slug(cls, id_or_slug: int | str) -> Dashboard:\n        if is_uuid(id_or_slug):\n            # just get dashboard if it's uuid\n            dashboard = Dashboard.get(id_or_slug)\n        else:\n            query = (\n                db.session.query(Dashboard)\n                .filter(id_or_slug_filter(id_or_slug))\n                .outerjoin(Dashboard.editors)\n            )\n            # Apply dashboard base filters\n            query = cls.base_filter(\"id\", SQLAInterface(Dashboard, db.session)).apply(\n                query, None\n            )\n            dashboard = query.one_or_none()\n        if not dashboard:\n            raise DashboardNotFoundError()\n\n        # make sure we still have basic access check from security manager\n        try:\n            dashboard.raise_for_access()\n        except SupersetSecurityException as ex:\n            raise DashboardAccessDeniedError() from ex\n\n        return dashboard\n\n    @staticmethod\n    def get_datasets_for_dashboard(id_or_slug: str) -> list[tuple[Any, dict[str, Any]]]:\n        dashboard = DashboardDAO.get_by_id_or_slug(id_or_slug)\n        return dashboard.datasets_trimmed_for_slices()\n\n    @staticmethod\n    def get_tabs_for_dashboard(id_or_slug: str) -> dict[str, Any]:\n        dashboard = DashboardDAO.get_by_id_or_slug(id_or_slug)\n        return dashboard.tabs","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/daos/dashboard.py#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nDashboardDAO.get_by_id_or_slug(\"q2-sales\")  # slug renamed to 'sales-q2'\n\n# after\n# resolve via the API filter on the immutable uuid\nGET /api/v1/dashboard/?q={\"filter\":[{\"col\":\"uuid\",\"opr\":\"eq\",\"value\":\"<uuid>\"}]}","handlingStrategy":"try-catch","validationCode":"def dashboard_exists_and_visible(id_or_slug: str) -> bool:\n    try:\n        DashboardDAO.get_by_id_or_slug(id_or_slug)\n        return True\n    except (DashboardNotFoundError, DashboardAccessDeniedError):\n        return False","typeGuard":"def is_dashboard_slug(s: str) -> bool:\n    return isinstance(s, str) and bool(s) and not s.isdigit()  # digit strings are ids","tryCatchPattern":"try:\n    dash = DashboardDAO.get_by_id_or_slug(id_or_slug)\nexcept DashboardNotFoundError:\n    abort(404)\nexcept DashboardAccessDeniedError:\n    abort(403)","preventionTips":["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."],"tags":["dao","dashboard","not-found","permissions","slug"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}