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 it

View on GitHub (pinned to f4587218dd)

Solutions

  1. Confirm existence with GET /api/v1/chart/{id} and correct the id.
  2. If the chart was deleted intentionally, create a new chart instead of updating.
  3. 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

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.