apache/superset · error · ReportScheduleUnexpectedError
Report schedule {id} ({name!r}) has no resolvable target (ch
Error message
Report schedule {id} ({name!r}) has no resolvable target (chart_id={chart_id}, dashboard_id={dashboard_id}); the report has neither a chart nor a dashboard. What it means
ReportScheduleUnexpectedError raised as a defensive fallback in _get_url when both chart and dashboard relationships are None AND neither chart_id nor dashboard_id is set — i.e. a malformed report row with no target at all. The message embeds the schedule id, name, and both null target ids so operators can identify the row directly.
Source
Thrown at superset/commands/report/execute.py:509
# 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."
)
force = "true" if self._report_schedule.force_screenshot else "false"
if chart:
if result_format in {
ChartDataResultFormat.CSV,
ChartDataResultFormat.XLSX,
ChartDataResultFormat.JSON,
ChartDataResultFormat.XLSX,
}:
return get_url_path(
"ChartDataRestApi.get_data",
pk=self._report_schedule.chart_id,View on GitHub (pinned to f4587218dd)
Solutions
- Inspect the row named in the message: SELECT * FROM report_schedule WHERE id = <id>
- Fix the row by setting a valid chart_id or dashboard_id, or delete the malformed schedule
- If a custom tool created this row, fix the tool to always set exactly one target
Example fix
-- before: malformed row UPDATE report_schedule SET chart_id = NULL WHERE id = 42; -- later execution fails -- after UPDATE report_schedule SET chart_id = 123 WHERE id = 42; -- valid target
Defensive patterns
Strategy: validation
Validate before calling
def report_has_target(report) -> bool:
return report.chart_id is not None or report.dashboard_id is not None Type guard
def is_well_formed_report(report_schedule) -> bool:
"""A report must carry exactly one non-null target id."""
return (report_schedule.chart_id is not None) ^ (report_schedule.dashboard_id is not None) Try / catch
try:
_get_url()
except ReportScheduleUnexpectedError as ex:
if 'no resolvable target' in str(ex):
# quarantine the malformed row named in the message
flag_for_repair(report_schedule.id) Prevention
- Never insert report_schedule rows by hand without exactly one target id
- Add a DB constraint or CI check that chart_id/dashboard_id are not both null
- Use the API for all report creation so validation always runs
When it happens
Trigger: A report_schedule row manually inserted (or corrupted) with chart_id and dashboard_id both NULL; bugs in import/export flows that strip target ids; direct DB edits. Normal API paths cannot create a target-less report.
Common situations: Migrations or manual SQL backfills that leave nulls; a partially applied update that cleared the target column; test fixtures created without targets.
Related errors
- The chart this report targets was deleted. Restore the chart
- The dashboard this report targets was deleted. Restore the d
- Screenshot failed; aborting to avoid sending a partial repor
- Failed taking a screenshot {str(ex)}
- Chart has no valid query context saved.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/b2f84fddf2bb9ada.
Report an issue: GitHub.