apache/superset · error · ReportScheduleTargetChartDeletedError

The chart this report targets was deleted. Restore the chart

Error message

The chart this report targets was deleted. Restore the chart, or update the report to point at an active chart.

What it means

ReportScheduleTargetChartDeletedError: ReportSchedule.chart is a visibility-filtered relationship, so a chart soft-deleted after the report was created loads as None while chart_id stays set. The _get_url choke point detects chart is None with chart_id set and raises this actionable error instead of silently falling through to the dashboard path and failing opaquely. It lands inside the state-machine envelope (ERROR log row plus notification dispatch).

Source

Thrown at superset/commands/report/execute.py:498

        Get the url for this report schedule: chart or dashboard
        """
        chart = self._report_schedule.chart
        dashboard = self._report_schedule.dashboard

        # Soft delete removed the FK-level guarantee that a report's target
        # chart exists: ``chart`` is a visibility-filtered relationship, so a
        # chart soft-deleted after this report was created (or attached via a
        # validate/commit race with DeleteChartCommand) loads as ``None``
        # while ``chart_id`` is still set. Without this guard the branch
        # below silently falls through to the dashboard path and fails
        # opaquely; raising here surfaces a clear, actionable error inside
        # the state-machine envelope (ERROR log row + notification dispatch).
        # Every content path (_get_screenshots, _get_csv_data,
        # _get_embedded_data, _get_notification_content) funnels through this
        # method, so this is the single choke point.
        if chart is None and dashboard is None:
            if self._report_schedule.chart_id is not None:
                raise ReportScheduleTargetChartDeletedError()
            # Symmetric guard for dashboard targets. Dashboard soft delete lands
            # in the sibling rollout; until then this cannot fire (a dashboard
            # with dependent reports cannot be deleted), which makes it inert
            # rather than wrong — and it keeps the report-target error vocabulary
            # parallel across entities from day one.
            if self._report_schedule.dashboard_id is not None:
                raise ReportScheduleTargetDashboardDeletedError()
            # Defensive fallback for a malformed report with no target IDs.
            # Missing relationships with a target ID are handled by the
            # dedicated deleted-target errors above.
            raise ReportScheduleUnexpectedError(
                f"Report schedule {self._report_schedule.id} "
                f"({self._report_schedule.name!r}) has no resolvable target "
                f"(chart_id={self._report_schedule.chart_id}, "
                f"dashboard_id={self._report_schedule.dashboard_id}); "
                "the report has neither a chart nor a dashboard."
            )

View on GitHub (pinned to f4587218dd)

Solutions

  1. Restore the chart from trash (undelete) so the relationship resolves again
  2. Or edit the report to target an active chart / dashboard
  3. Going forward, check dependents before deleting charts (the delete API reports which reports reference a chart)
Defensive patterns

Strategy: try-catch

Validate before calling

from superset.commands.report.exceptions import ReportScheduleTargetChartDeletedError

def report_target_ok(report) -> bool:
    return report.chart_id is None or report.chart is not None

Type guard

def has_live_chart_target(report_schedule) -> bool:
    """True when the report either has no chart target or the chart is not soft-deleted."""
    return report_schedule.chart_id is None or report_schedule.chart is not None

Try / catch

try:
    _get_url()
except ReportScheduleTargetChartDeletedError:
    # notify owner: restore chart from trash or retarget the report
    notify_owner(report_schedule, 'target chart deleted')

Prevention

When it happens

Trigger: Report targets a chart that is later soft-deleted (trash); a validate/commit race with DeleteChartCommand removes the chart between report creation and execution; the next scheduled run calls _get_url/_get_screenshots/_get_csv_data and hits the guard.

Common situations: Chart cleanup sweeps that soft-delete unused charts without checking dependent reports; users deleting a chart from the chart list not realizing a report/alert points at it.

Related errors


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