apache/superset · error · DashboardForbiddenError

Changing this Dashboard is forbidden

Error message

Changing this Dashboard is forbidden

What it means

DashboardForbiddenError is raised by CopyDashboardCommand.validate() when security_manager.is_editor(original_dashboard) returns False. Superset requires editor-level rights on the source dashboard (owner, admin, or a role with the appropriate can_edit capability) before allowing a copy, because the copy exposes the full dashboard definition.

Source

Thrown at superset/commands/dashboard/copy.py:64

        # dashboard's baseline records read as "Cloned from <source>"
        # in the timeline instead of "Dashboard created".
        # Method-scoped imports — defer the versioning bootstrap path
        # (``Model.metadata`` and Continuum-adjacent setup) out of this
        # command's module-load graph; see ``changes.py`` module
        # docstring for the broader init-order rationale.
        from superset import db
        from superset.versioning.changes import ACTION_KIND_CLONE, ACTION_KIND_KEY

        db.session.info[ACTION_KIND_KEY] = ACTION_KIND_CLONE
        return DashboardDAO.copy_dashboard(self._original_dash, self._properties)

    def validate(self) -> None:
        if not self._properties.get("dashboard_title") or not self._properties.get(
            "json_metadata"
        ):
            raise DashboardInvalidError()
        if not security_manager.is_editor(self._original_dash):
            raise DashboardForbiddenError()

View on GitHub (pinned to f4587218dd)

Solutions

  1. Ask an owner or admin to add the calling user as an owner (or editor) of the source dashboard, then retry the copy.
  2. Use an admin account for bulk copy automation.
  3. If the policy should allow viewers to copy, grant the role the dashboard edit permission via Roles -> Permissions, understanding this widens edit rights too.

Example fix

# before
CopyDashboardCommand(dash, props).run()  # user is viewer only

# after
from superset.extensions import security_manager
if security_manager.is_editor(dash):
    CopyDashboardCommand(dash, props).run()
else:
    raise PermissionError("Request ownership of the dashboard before copying")
Defensive patterns

Strategy: try-catch

Validate before calling

from superset.extensions import security_manager

if not security_manager.is_editor(src_dashboard):
    raise PermissionError('must be an editor/owner of the dashboard to copy it')

Try / catch

try:
    CopyDashboardCommand(src, props).run()
except DashboardForbiddenError:
    prompt_user_for_ownership_or_use_admin()

Prevention

When it happens

Trigger: Calling the dashboard copy API as a user who can view but not edit the source dashboard: not an owner, not an admin, and role lacks the dashboard edit permission.

Common situations: Viewer/Gamma-style roles attempting to duplicate shared dashboards; users assuming 'can view' implies 'can copy'; org policies where dashboards are owned by a service account and nobody else can copy them.

Understand the failure class

Related errors


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