{"record":{"id":"bd6bc2b952698080","repo":"apache/superset","slug":"chart-chart-id-s-is-not-on-dashboard-dashboard","errorCode":null,"errorMessage":"Chart %(chart_id)s is not on dashboard %(dashboard_id)s","messagePattern":"Chart (.+?) is not on dashboard (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"superset/charts/data/dashboard_filter_context.py","lineNumber":249,"sourceCode":"        if isinstance(column, dict):\n            return column.get(\"name\")\n        if isinstance(column, str):\n            return column\n    return None\n\n\ndef _validate_chart_on_dashboard(\n    dashboard: Dashboard,\n    chart_id: int,\n) -> None:\n    \"\"\"\n    Validate that a chart belongs to a dashboard.\n\n    :raises ValueError: if the chart is not found on the dashboard\n    \"\"\"\n    slice_ids = {slc.id for slc in dashboard.slices}\n    if chart_id not in slice_ids:\n        raise ValueError(\n            _(\n                \"Chart %(chart_id)s is not on dashboard %(dashboard_id)s\",\n                chart_id=chart_id,\n                dashboard_id=dashboard.id,\n            )\n        )\n\n\ndef _check_dashboard_access(dashboard: Dashboard) -> None:\n    \"\"\"\n    Check that the user has access to the dashboard.\n    Uses the security manager's raise_for_access which handles\n    guest users, admins, editors, and viewer access.\n\n    :raises SupersetSecurityException: if the user cannot access the dashboard\n    \"\"\"\n    security_manager.raise_for_access(dashboard=dashboard)\n","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/charts/data/dashboard_filter_context.py#L231-L267","documentation":"ValueError raised by _validate_chart_on_dashboard in the dashboard filter context pipeline (used by chart data requests that apply dashboard-level filters): it collects the slice ids attached to the dashboard and raises when the requested chart_id is not among them. A chart must be part of the dashboard for its data request to be evaluated in that dashboard's filter context.","triggerScenarios":"Requesting chart data with a dashboard_id and a chart_id for a chart that was removed from that dashboard, belongs to a different dashboard, or whose layout entry was deleted while stale form_data still references the old pairing; also chart/dashboard id mix-ups after imports re-assign ids.","commonSituations":"Stale browser state: a dashboard tab open from before an edit removed the chart, and the client re-issues the chart's data request with nativeFilters/dashboard context; cross-dashboard copied charts where the old dashboard_id lingers in form_data; import/export flows where native filter or layout metadata references chart ids not present on the target dashboard.","solutions":["Refresh the dashboard in the browser so form_data is re-synced with the current dashboard layout.","If you maintain the payload, verify chart_id is actually in dashboard.slices (e.g. GET the dashboard and check its chart ids) before requesting data with that dashboard context.","For imports, re-map chart ids consistently so dashboard layout and filter metadata reference charts that exist on the imported dashboard.","Remove/re-add the chart to the dashboard if the layout JSON is out of sync with the slice relationship."],"exampleFix":"# before\npayload = {\"form_data\": {\"slice_id\": 42, \"dashboard_id\": 7}}  # chart 42 not on dashboard 7\nresp = requests.post(\"/api/v1/chart/data\", json=payload)\n\n# after: confirm membership first\ndash = requests.get(\"/api/v1/dashboard/7\", headers=auth).json()[\"result\"]\nchart_ids = {c[\"slice_id\"] for c in dash[\"position_slices\"]}  # or dash['slices']\nassert 42 in chart_ids, \"chart not on dashboard; refresh or fix dashboard layout\"","handlingStrategy":"validation","validationCode":"slice_ids = {slc.id for slc in dashboard.slices}\nif chart_id not in slice_ids:\n    raise ValueError(\n        f\"chart {chart_id} not on dashboard {dashboard.id}; refresh or fix dashboard layout\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    ctx = build_dashboard_filter_context(dashboard, chart_id, form_data)\nexcept ValueError as ex:\n    if \"is not on dashboard\" in str(ex):\n        # stale client state: refetch dashboard metadata and re-sync form_data\n        refetch_and_retry()","preventionTips":["After editing a dashboard (removing charts), reload dependent tabs before issuing chart-data requests with dashboard context.","On import/export, re-map chart ids consistently across layout, native filters, and chart metadata."],"tags":["rest-api","charts","dashboards","validation","stale-state"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}