apache/superset · error · ValueError

Dashboard %(dashboard_id)s not found

Error message

Dashboard %(dashboard_id)s not found

What it means

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.

Source

Thrown at superset/charts/data/dashboard_filter_context.py:298

    and returns the merged extra_form_data along with metadata about each filter.

    When ``active_data_mask`` is provided (e.g. the live filter state from a
    dashboard view), each in-scope filter present in the mask uses its active
    ``extraFormData`` instead of the saved default; an empty active value means
    the filter was cleared. Filters absent from the mask fall back to their
    saved defaults, so omitting ``active_data_mask`` reproduces the dashboard's
    initial-load behavior.

    :param dashboard_id: The ID of the dashboard
    :param chart_id: The ID of the chart
    :param active_data_mask: Optional live filter state keyed by native filter id
    :returns: DashboardFilterContext with merged extra_form_data and filter metadata
    :raises ValueError: if dashboard not found or chart not on dashboard
    :raises SupersetSecurityException: if the user cannot access the dashboard
    """
    dashboard = db.session.query(Dashboard).filter_by(id=dashboard_id).one_or_none()
    if not dashboard:
        raise ValueError(
            _("Dashboard %(dashboard_id)s not found", dashboard_id=dashboard_id)
        )

    _check_dashboard_access(dashboard)
    _validate_chart_on_dashboard(dashboard, chart_id)

    metadata = json.loads(dashboard.json_metadata or "{}")
    native_filter_config: list[dict[str, Any]] = metadata.get(
        "native_filter_configuration", []
    )

    position_json: dict[str, Any] = json.loads(dashboard.position_json or "{}")

    context = DashboardFilterContext()

    for flt in native_filter_config:
        flt_type = flt.get("type", "")
        if flt_type == "DIVIDER":

View on GitHub (pinned to f4587218dd)

Solutions

  1. Verify the dashboard exists: GET /api/v1/dashboard/<dashboard_id> before issuing the chart data request.
  2. If the dashboard was deleted, reload the dashboard list in the client and drop the stale dashboard_id from the chart-data request body.
  3. Confirm you are sending the integer dashboard id, not the UUID, where the API expects the PK.
  4. In custom code calling get_dashboard_filter_context, wrap the call in try/except ValueError and map it to a 404 response.

Example fix

# before
ctx = get_dashboard_filter_context(dashboard_id=dashboard_id, chart_id=chart_id)

# after
from superset.models.dashboard import Dashboard
from superset import db

dashboard = db.session.query(Dashboard).filter_by(id=dashboard_id).one_or_none()
if dashboard is None:
    abort(404, description=f"Dashboard {dashboard_id} not found")
ctx = get_dashboard_filter_context(dashboard_id=dashboard_id, chart_id=chart_id)
Defensive patterns

Strategy: validation

Validate before calling

from superset import db
from superset.models.dashboard import Dashboard

def dashboard_exists(dashboard_id: int) -> bool:
    return (
        db.session.query(Dashboard.id)
        .filter_by(id=dashboard_id)
        .one_or_none()
        is not None
    )

if not dashboard_exists(dashboard_id):
    return jsonify({"error": f"dashboard {dashboard_id} not found"}), 404
ctx = get_dashboard_filter_context(dashboard_id, chart_id)

Type guard

def is_valid_dashboard_id(value: Any) -> TypeGuard[int]:
    return isinstance(value, int) and value > 0

Try / catch

try:
    ctx = get_dashboard_filter_context(dashboard_id, chart_id)
except ValueError as ex:
    if "not found" in str(ex):
        return abort(404, description=str(ex))
    raise

Prevention

When it happens

Trigger: 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>.

Common situations: 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.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/83900cf1e5d7e211. Report an issue: GitHub.