apache/superset · error · ImportFailedError
Dashboard was deleted and re-import requires can_write permi
Error message
Dashboard was deleted and re-import requires can_write permission to restore it
What it means
ImportFailedError('Dashboard was deleted and re-import requires can_write permission to restore it') is raised in the v1 import path when the bundle's dashboard UUID matches a soft-deleted dashboard row (deleted_at set) and the importer lacks can_write (import permission). Re-importing a soft-deleted UUID is treated as an implicit restore, which is a write-level operation, so it is refused rather than silently reviving the row.
Source
Thrown at superset/commands/dashboard/importers/v1/utils.py:337
"Dashboard",
)
# `user` is None for background / example-loader paths (no Flask request
# user). Combined with ``can_write=True`` (typically from
# ``ignore_permissions=True``), the editorship checks in the restore /
# overwrite branches below are intentionally skipped because the caller has
# already established trust at the command level.
user = get_user()
if existing := find_existing_for_import(Dashboard, config["uuid"]):
if existing.deleted_at is not None:
# RESTORE path — re-importing a soft-deleted UUID is an implicit
# restore-with-update, a distinct operation from overwriting an
# alive row, so it is handled in its own branch.
if not can_write:
# Case B: don't silently return a soft-deleted row to a caller
# without write permission — that would let a dependent import
# (e.g. a dashboard zip referencing this dashboard) reattach to
# a deleted dashboard.
raise ImportFailedError(
"Dashboard was deleted and re-import requires can_write "
"permission to restore it"
)
# ``user`` is None on background / example-loader paths (no Flask
# request user); combined with ``can_write`` (typically from
# ``ignore_permissions=True``) the editorship check is intentionally
# skipped because the caller already established trust.
if user and (
not security_manager.can_access_dashboard(existing)
or (
not security_manager.is_editor(existing)
and not security_manager.is_admin()
)
):
raise ImportFailedError(
"A dashboard already exists and user doesn't have "
"permissions to restore it"
)View on GitHub (pinned to f4587218dd)
Solutions
- Run the import with a user/role that has dashboard write permission (can_write / can_import on Dashboard).
- Or purge the soft-deleted dashboard first (hard-delete via the API's purge path or admin) so the UUID is free and the import becomes a plain create — still requiring create permission.
- If the dashboard should stay deleted, remove it from the bundle or change its UUID before import.
Example fix
# before
client.post('/api/v1/dashboard/import/', ...) # viewer token, UUID soft-deleted
# after
# 1) purge the soft-deleted row as admin, or
# 2) re-run import with a role that has can_write on Dashboard
admin_client.post('/api/v1/dashboard/import/', files=...) Defensive patterns
Strategy: try-catch
Validate before calling
from superset.commands.dashboard.importers.v1.utils import find_existing_for_import
from superset.models.dashboard import Dashboard
existing = find_existing_for_import(Dashboard, config['uuid'])
if existing is not None and existing.deleted_at is not None:
if not security_manager.can_access('can_write', 'Dashboard'):
raise PermissionError('re-import of soft-deleted UUID needs can_write') Try / catch
try:
run_import(bundle)
except ImportFailedError as ex:
if 'requires can_write permission to restore' in str(ex):
escalate_to_writer_or_purge_soft_deleted_row() Prevention
- Run restore-by-import with roles holding Dashboard can_write.
- Hard-delete (purge) dashboards you never intend to restore, to free the UUID.
- Track which bundle UUIDs correspond to soft-deleted rows in target environments.
When it happens
Trigger: Importing a v1 dashboard ZIP whose dashboard UUID corresponds to a dashboard that was soft-deleted in the target instance, using an account (or token) without dashboard write/import permission.
Common situations: Re-importing an old export after the dashboard was deleted during cleanup; automated sync pipelines that push bundles with a viewer-level service account; deleted dashboards in the trash-like soft-delete state blocking re-import for non-writers.
Related errors
- A dashboard already exists and user doesn't have permissions
- User doesn't have permission to create or update datasets
- A dashboard already exists and user doesn't have permissions
- Dashboard doesn't exist and user doesn't have permission to
- Cannot convert node type: ${node.type}
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/402aae1f35ecc21f.
Report an issue: GitHub.