apache/superset · error · ChartDeleteFailedReportsExistError
There are associated alerts or reports: %(report_names)s
Error message
There are associated alerts or reports: %(report_names)s
What it means
Raised as ChartDeleteFailedReportsExistError when ReportScheduleDAO.find_by_chart_ids finds at least one alert or report schedule that renders the chart being deleted. Superset blocks the delete to keep scheduled alerts/reports from silently breaking, and the message lists the offending report names.
Source
Thrown at superset/commands/chart/delete.py:59
def __init__(self, model_ids: list[int]):
self._model_ids = model_ids
self._models: Optional[list[Slice]] = None
@transaction(on_error=partial(on_error, reraise=ChartDeleteFailedError))
def run(self) -> None:
self.validate()
assert self._models
ChartDAO.delete(self._models)
def validate(self) -> None:
# Validate/populate model exists
self._models = ChartDAO.find_by_ids(self._model_ids)
if not self._models or len(self._models) != len(self._model_ids):
raise ChartNotFoundError()
# Check there are no associated ReportSchedules
if reports := ReportScheduleDAO.find_by_chart_ids(self._model_ids):
report_names = [report.name for report in reports]
raise ChartDeleteFailedReportsExistError(
_(
"There are associated alerts or reports: %(report_names)s",
report_names=",".join(report_names),
)
)
# Check editorship
for model in self._models:
try:
security_manager.raise_for_editorship(model)
except SupersetSecurityException as ex:
raise ChartForbiddenError() from ex
View on GitHub (pinned to f4587218dd)
Solutions
- Open Alerts & Reports in the UI, find the schedules named in the error, and either delete them or repoint them to another chart.
- Or via API: GET /api/v1/report/?q=... to find schedules referencing the chart, then DELETE them.
- Retry the chart delete once no ReportSchedule references the chart ids.
Example fix
# before
client.delete('/api/v1/chart/', json={'ids': [42]}) # ChartDeleteFailedReportsExistError
# after: remove blocking schedules first
reports = client.get('/api/v1/report/').json()
# find report whose chart is 42, then:
client.delete(f"/api/v1/report/{blocking_report_id}")
client.delete('/api/v1/chart/', json={'ids': [42]}) Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.report import ReportScheduleDAO
if ReportScheduleDAO.find_by_chart_ids(chart_ids):
raise ValueError('chart is referenced by alerts/reports; remove them first') Try / catch
from superset.commands.chart.exceptions import ChartDeleteFailedReportsExistError
try:
DeleteChartCommand(ids).run()
except ChartDeleteFailedReportsExistError as ex:
# ex.message lists the blocking report names
detach_or_delete_reports(ex.message) Prevention
- Check the Alerts & Reports page before deleting charts.
- Automate a pre-delete check via ReportScheduleDAO.find_by_chart_ids.
- Document chart-to-report dependencies in team runbooks.
When it happens
Trigger: DELETE /api/v1/chart/ for a chart attached to an Alert/Report schedule (delivered via email/Slack etc.); deleting a chart that sits on a dashboard targeted by a dashboard-report after the schedule was created against the chart itself.
Common situations: Cleaning up old charts without checking the Alerts & Reports page; inherited environments where legacy report schedules are invisible in the chart's UI.
Related errors
- Chart not found.
- There are associated alerts or reports: %(report_names)s
- There are associated alerts or reports: %(report_names)s
- Cannot delete a database that has datasets attached
- Report Schedule not found.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/0bfc3e7e49a1134b.
Report an issue: GitHub.