apache/superset · error · SystemThemeInUseError

Cannot delete theme that is set as system default or dark th

Error message

Cannot delete theme that is set as system default or dark theme.

What it means

SystemThemeInUseError raised when a theme in the delete set is currently referenced as the deployment's system default theme or system dark theme (is_system_default / is_system_dark flags on the row). Deleting the active default would leave the deployment without a fallback theme, so validate() rejects the bulk delete before _dissociate_dashboards or ThemeDAO.delete run.

Source

Thrown at superset/commands/theme/delete.py:64

        # Dissociate dashboards from themes before deleting
        self._dissociate_dashboards()

        ThemeDAO.delete(self._models)

    def validate(self) -> None:
        # Validate/populate model exists
        self._models = ThemeDAO.find_by_ids(self._model_ids)
        if not self._models or len(self._models) != len(self._model_ids):
            raise ThemeNotFoundError()

        # Check if any of the themes are system themes
        for theme in self._models:
            if theme.is_system:
                raise SystemThemeProtectedError()
            # Check if theme is in use as system default or dark
            if theme.is_system_default or theme.is_system_dark:
                raise SystemThemeInUseError()

        # Check for dashboard usage
        self._dashboard_usage = self._get_dashboard_usage()

    def _dissociate_dashboards(self) -> None:
        """Dissociate dashboards from themes before deletion."""
        from superset.models.dashboard import Dashboard

        theme_ids = [theme.id for theme in self._models or []]
        if not theme_ids:
            return

        # Get count of affected dashboards for logging
        affected_count = (
            db.session.query(Dashboard)
            .filter(Dashboard.theme_id.in_(theme_ids))
            .count()
        )

View on GitHub (pinned to f4587218dd)

Solutions

  1. Switch the system default/dark theme configuration to another theme first, then delete the old one.
  2. Clear is_system_default/is_system_dark on the row (via admin theme settings) before deletion if it is genuinely no longer the default.
  3. Exclude in-use themes from bulk delete payloads programmatically.

Example fix

# before (theme 5 is configured default)
DeleteThemesCommand([5]).run()  # SystemThemeInUseError
# after
set_system_default_theme(other_theme_id)
DeleteThemesCommand([5]).run()
Defensive patterns

Strategy: validation

Validate before calling

in_use = {t.id for t in themes if t.is_system_default or t.is_system_dark}
payload = [i for i in ids if i not in in_use]

Type guard

def is_theme_in_use(theme) -> bool:
    return bool(theme.is_system_default or theme.is_system_dark)

Try / catch

try:
    DeleteThemesCommand(ids).run()
except SystemThemeInUseError:
    reassign_system_defaults()
    retry_once()

Prevention

When it happens

Trigger: Deleting the theme currently selected in configuration as THEME.DEFAULT / dark variant, or any theme row whose is_system_default/is_system_dark flags are set, as part of a bulk delete.

Common situations: Rebranding flows that delete the old corporate theme while it is still the configured default; cleanup scripts unaware of the config linkage.

Related errors


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