apache/superset · error · ReportScheduleScreenshotFailedError

Failed taking a screenshot {str(ex)}

Error message

Failed taking a screenshot {str(ex)}

What it means

ReportScheduleScreenshotFailedError wrapping an unexpected exception from the screenshot path: after logging a 'report_capture_terminal' error line (with elapsed seconds, remaining budget, and the terminal exception type name), the generic Exception is re-raised as this typed error with the original message appended ('Failed taking a screenshot {str(ex)}').

Source

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

        except ReportExecutionBudgetExceededError:
            raise
        except Exception as ex:
            elapsed_seconds = (
                datetime.now(timezone.utc).replace(tzinfo=None) - start_time
            ).total_seconds()
            logger.error(
                "report_capture_terminal %s elapsed_seconds=%.2f "
                "remaining_seconds=%s terminal_reason=%s",
                self._log_context,
                elapsed_seconds,
                (
                    f"{self._report_execution_context.deadline.remaining_seconds:.2f}"
                    if self._report_execution_context
                    else None
                ),
                type(ex).__name__,
            )
            raise ReportScheduleScreenshotFailedError(
                f"Failed taking a screenshot {str(ex)}"
            ) from ex
        if not imges:
            raise ReportScheduleScreenshotFailedError()
        return imges

    def _get_pdf(self) -> bytes:
        """
        Get chart or dashboard pdf
        :raises: ReportSchedulePdfFailedError
        """
        screenshots = self._get_screenshots()
        reserve_seconds = (
            self._report_execution_context.post_capture_reserve_seconds
            if self._report_execution_context
            else 0.0
        )
        self._phase_timeout(

View on GitHub (pinned to f4587218dd)

Solutions

  1. Read the terminal_reason in the preceding log line — it names the underlying exception type to chase
  2. Verify the screenshot/playwright worker is up and the configured internal endpoint (SUPERSET_WEBDRIVER/SCREENSHOT service) is reachable from the worker
  3. Reproduce manually: log in as the executor user and open the report URL the worker captures
Defensive patterns

Strategy: try-catch

Validate before calling

def screenshot_service_healthy(base_url: str) -> bool:
    import requests
    try:
        return requests.get(base_url, timeout=5).status_code < 500
    except requests.RequestException:
        return False

Try / catch

try:
    _get_screenshots()
except ReportScheduleScreenshotFailedError as ex:
    # str(ex) embeds the underlying cause; log terminal_reason for triage
    logger.error('screenshot failed: %s', ex)
    raise

Prevention

When it happens

Trigger: Any non-timeout exception inside get_screenshot: playwright connection refused (screenshot service down), HTTP error fetching the report URL, auth failure during the capture session, unexpected None attribute in the playwright wrapper.

Common situations: Screenshot service (windowed playwright) not running or unreachable; SESSION cookie/token issues for the executor user; upgrades that changed the playwright protocol; TLS certificate problems on the internal report URL.

Related errors


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