apache/superset · error · ChartNotFoundError
Chart not found.
Error message
Chart not found.
What it means
Raised as ChartNotFoundError in UpdateChartCommand.validate() when ChartDAO.find_by_id(self._model_id) returns None: the chart id being updated does not exist. The update aborts before any property validation runs.
Source
Thrown at superset/commands/chart/update.py:176
exceptions.append(ChartQueryContextDatasourceMismatchValidationError())
def validate(self) -> None: # noqa: C901
exceptions: list[ValidationError] = []
dashboard_ids = self._properties.get("dashboards")
tag_ids: Optional[list[int]] = self._properties.get("tags")
# Validate if datasource_id is provided datasource_type is required
datasource_id = self._properties.get("datasource_id")
datasource_type = ""
if datasource_id is not None:
datasource_type = self._properties.get("datasource_type", "")
if not datasource_type:
exceptions.append(DatasourceTypeUpdateRequiredValidationError())
# Validate/populate model exists
self._model = ChartDAO.find_by_id(self._model_id)
if not self._model:
raise ChartNotFoundError()
# Check and update editorship; when only updating query context we relax
# editorship so report workers can save context. We still require chart
# access so users cannot rewrite query context for charts they cannot access.
if not is_query_context_update(self._properties):
try:
security_manager.raise_for_editorship(self._model)
compute_subjects(self._model, self._properties, exceptions)
except SupersetSecurityException as ex:
raise ChartForbiddenError() from ex
except ValidationError as ex:
exceptions.append(ex)
else:
try:
security_manager.raise_for_access(chart=self._model)
except SupersetSecurityException as ex:
raise ChartForbiddenError() from ex
# Keep the refreshed payload bound to the chart's own datasource so itView on GitHub (pinned to f4587218dd)
Solutions
- Confirm existence with GET /api/v1/chart/{id} and correct the id.
- If the chart was deleted intentionally, create a new chart instead of updating.
- Reload Explore from the chart list to pick up the current id.
Example fix
# before
client.put('/api/v1/chart/999', json={'slice_name': 'renamed'}) # 404 ChartNotFoundError
# after
chart = client.get('/api/v1/chart/999')
if chart.status_code == 200:
client.put('/api/v1/chart/999', json={'slice_name': 'renamed'}) Defensive patterns
Strategy: validation
Validate before calling
if not ChartDAO.find_by_id(chart_id):
raise ValueError(f'chart {chart_id} does not exist') Try / catch
from superset.commands.chart.exceptions import ChartNotFoundError
try:
UpdateChartCommand(chart_id, props).run()
except ChartNotFoundError:
reload_and_recreate_or_retarget() Prevention
- Re-fetch chart ids before updates in long-lived sessions.
- Handle 404 in chart-edit scripts by refreshing state.
When it happens
Trigger: PUT /api/v1/chart/{id} with a deleted or never-existing id; updating from a stale Explore session after the chart was removed; id confusion across environments.
Common situations: Long-lived Explore tabs referencing a chart deleted elsewhere; CI scripts reusing recorded ids against a reset database.
Related errors
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/2749b48c66272c53.
Report an issue: GitHub.