{"record":{"id":"83900cf1e5d7e211","repo":"apache/superset","slug":"dashboard-dashboard-id-s-not-found","errorCode":null,"errorMessage":"Dashboard %(dashboard_id)s not found","messagePattern":"Dashboard (.+?) not found","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"superset/charts/data/dashboard_filter_context.py","lineNumber":298,"sourceCode":"    and returns the merged extra_form_data along with metadata about each filter.\n\n    When ``active_data_mask`` is provided (e.g. the live filter state from a\n    dashboard view), each in-scope filter present in the mask uses its active\n    ``extraFormData`` instead of the saved default; an empty active value means\n    the filter was cleared. Filters absent from the mask fall back to their\n    saved defaults, so omitting ``active_data_mask`` reproduces the dashboard's\n    initial-load behavior.\n\n    :param dashboard_id: The ID of the dashboard\n    :param chart_id: The ID of the chart\n    :param active_data_mask: Optional live filter state keyed by native filter id\n    :returns: DashboardFilterContext with merged extra_form_data and filter metadata\n    :raises ValueError: if dashboard not found or chart not on dashboard\n    :raises SupersetSecurityException: if the user cannot access the dashboard\n    \"\"\"\n    dashboard = db.session.query(Dashboard).filter_by(id=dashboard_id).one_or_none()\n    if not dashboard:\n        raise ValueError(\n            _(\"Dashboard %(dashboard_id)s not found\", dashboard_id=dashboard_id)\n        )\n\n    _check_dashboard_access(dashboard)\n    _validate_chart_on_dashboard(dashboard, chart_id)\n\n    metadata = json.loads(dashboard.json_metadata or \"{}\")\n    native_filter_config: list[dict[str, Any]] = metadata.get(\n        \"native_filter_configuration\", []\n    )\n\n    position_json: dict[str, Any] = json.loads(dashboard.position_json or \"{}\")\n\n    context = DashboardFilterContext()\n\n    for flt in native_filter_config:\n        flt_type = flt.get(\"type\", \"\")\n        if flt_type == \"DIVIDER\":","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/charts/data/dashboard_filter_context.py#L280-L316","documentation":"Raised as a ValueError by get_dashboard_filter_context() when the dashboard_id passed to the chart-data API does not match any row in the Dashboard table (db.session.query(Dashboard).filter_by(id=...).one_or_none() returns None). The chart data endpoint (/api/v1/chart/<id>/data with dashboard_id in the body) uses this helper to reproduce a chart's in-dashboard filter context, so an unknown or deleted dashboard cannot be resolved. It is a plain ValueError, not a Superset command exception, so it surfaces as an unhandled 500 unless caught upstream.","triggerScenarios":"POST /api/v1/chart/<chart_id>/data with a dashboard_id that was deleted, belongs to another instance, or is a string/UUID where an integer PK is expected; calling get_dashboard_filter_context(dashboard_id=...) directly with a stale id after the dashboard was removed via the UI or REST DELETE /api/v1/dashboard/<id>.","commonSituations":"Dashboard was deleted while a user had an old browser tab open and the chart then re-requests data embedding the stale dashboard_id; scripts replaying captured chart-data payloads against a refreshed metadata DB; passing dashboard uuid instead of integer id on Superset versions where the field is the integer PK.","solutions":["Verify the dashboard exists: GET /api/v1/dashboard/<dashboard_id> before issuing the chart data request.","If the dashboard was deleted, reload the dashboard list in the client and drop the stale dashboard_id from the chart-data request body.","Confirm you are sending the integer dashboard id, not the UUID, where the API expects the PK.","In custom code calling get_dashboard_filter_context, wrap the call in try/except ValueError and map it to a 404 response."],"exampleFix":"# before\nctx = get_dashboard_filter_context(dashboard_id=dashboard_id, chart_id=chart_id)\n\n# after\nfrom superset.models.dashboard import Dashboard\nfrom superset import db\n\ndashboard = db.session.query(Dashboard).filter_by(id=dashboard_id).one_or_none()\nif dashboard is None:\n    abort(404, description=f\"Dashboard {dashboard_id} not found\")\nctx = get_dashboard_filter_context(dashboard_id=dashboard_id, chart_id=chart_id)","handlingStrategy":"validation","validationCode":"from superset import db\nfrom superset.models.dashboard import Dashboard\n\ndef dashboard_exists(dashboard_id: int) -> bool:\n    return (\n        db.session.query(Dashboard.id)\n        .filter_by(id=dashboard_id)\n        .one_or_none()\n        is not None\n    )\n\nif not dashboard_exists(dashboard_id):\n    return jsonify({\"error\": f\"dashboard {dashboard_id} not found\"}), 404\nctx = get_dashboard_filter_context(dashboard_id, chart_id)","typeGuard":"def is_valid_dashboard_id(value: Any) -> TypeGuard[int]:\n    return isinstance(value, int) and value > 0","tryCatchPattern":"try:\n    ctx = get_dashboard_filter_context(dashboard_id, chart_id)\nexcept ValueError as ex:\n    if \"not found\" in str(ex):\n        return abort(404, description=str(ex))\n    raise","preventionTips":["Always resolve the dashboard through GET /api/v1/dashboard/<id> before embedding dashboard_id in chart-data requests.","In clients, clear dashboard_id from stored payloads when a 404 on the dashboard is observed.","Never substitute a dashboard UUID where the integer PK is expected."],"tags":["dashboard","not-found","validation","api"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}