apache/superset · error · ChartForbiddenError

Changing this chart is forbidden

Error message

Changing this chart is forbidden

What it means

ChartForbiddenError (ForbiddenError subclass, HTTP 403) raised in ChartCreateCommand.validate() when security_manager.raise_for_access(datasource=...) throws SupersetSecurityException while resolving the chart's datasource. Creating a chart requires the caller to have access to the target dataset; the original security exception is chained via 'from ex'.

Source

Thrown at superset/commands/chart/create.py:78

        self._properties["last_saved_by"] = g.user
        chart = ChartDAO.create(attributes=self._properties)
        if after_create := current_app.config.get("AFTER_ASSET_CREATE"):
            after_create(chart, "chart")
        return chart

    def validate(self) -> None:
        exceptions = []
        datasource_type = self._properties["datasource_type"]
        datasource_id = self._properties["datasource_id"]
        dashboard_ids = self._properties.get("dashboards", [])

        # Validate/Populate datasource
        try:
            datasource = get_datasource_by_id(datasource_id, datasource_type)
            self._properties["datasource_name"] = datasource.name
            security_manager.raise_for_access(datasource=datasource)
        except SupersetSecurityException as ex:
            raise ChartForbiddenError() from ex
        except ValidationError as ex:
            exceptions.append(ex)

        # Validate/Populate dashboards
        dashboards = DashboardDAO.find_by_ids(dashboard_ids)
        if len(dashboards) != len(dashboard_ids):
            exceptions.append(DashboardsNotFoundValidationError())
        for dash in dashboards:
            if not security_manager.is_editor(dash):
                raise DashboardsForbiddenError()
        self._properties["dashboards"] = dashboards

        populate_subjects(self._properties, exceptions)

        if exceptions:
            raise ChartInvalidError(exceptions=exceptions)

View on GitHub (pinned to f4587218dd)

Solutions

  1. Grant the user's role access to the dataset (Access requests / Security > List of Chart Roles or dataset permission) and retry.
  2. Verify access first with GET /api/v1/dataset/<id> as the same user.
  3. If using RLS or custom security managers, confirm raise_for_access rules actually permit this principal for this datasource.

Example fix

# before (as Gamma user)
POST /api/v1/chart/ {"datasource_id": 7, "datasource_type": "table", ...}  # 403

# after (admin grants access)
# Security > Roles > Gamma > Permissions: add 'can read on Dataset (id:7)'
# then retry the same POST
Defensive patterns

Strategy: try-catch

Validate before calling

from superset import security_manager
from superset.utils.core import get_datasource_by_id

def can_use_datasource(datasource_id: int, datasource_type: str) -> bool:
    try:
        ds = get_datasource_by_id(datasource_id, datasource_type)
        security_manager.raise_for_access(datasource=ds)
        return True
    except Exception:
        return False

Try / catch

try:
    CreateChartCommand(properties).run()
except ChartForbiddenError:
    return {"error": "no access to datasource; request dataset permission"}, 403

Prevention

When it happens

Trigger: POST /api/v1/chart/ with datasource_id/datasource_type the user cannot access (no dataset permission, RLS-blocked, Gamma without 'can read on dataset'); referencing a dataset in a database the role cannot query.

Common situations: Gamma users creating charts via API without the dataset grant; admins testing with a limited role; datasets whose access was revoked after an export/import between environments.

Understand the failure class

Related errors


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