apache/superset · error · ImportFailedError
Dataset {existing.table_name!r} (uuid {config['uuid']}) was
Error message
Dataset {existing.table_name!r} (uuid {config['uuid']}) was deleted and re-import requires can_write permission to restore it What it means
During v1 dataset import, when the uploaded UUID matches an existing soft-deleted (deleted_at set) dataset and the caller lacks can_write (dataset write permission), ImportFailedError is raised instead of silently returning the deleted row. The guard exists because returning the soft-deleted row would let the importer reattach charts/dashboards to a deleted dataset and produce broken artifacts.
Source
Thrown at superset/commands/dataset/importers/v1/utils.py:261
# overwrite branches below are intentionally skipped because the caller has
# already established trust at the command level.
user = get_user()
# Tracks whether we entered the soft-deleted mutation path so the
# downstream `sync` decision (below) can reflect that an
# implicit-restore re-import is a clean replacement, not a merge.
is_soft_deleted_match = False
if existing := find_existing_for_import(SqlaTable, 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 the importer
# reattach charts/dashboards to a deleted dataset and produce
# broken charts.
raise ImportFailedError(
f"Dataset {existing.table_name!r} (uuid {config['uuid']}) "
"was deleted and re-import requires can_write permission "
"to restore it"
)
# ``user`` is None on background / example-loader paths; 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.is_editor(existing)
and not security_manager.is_admin()
):
raise ImportFailedError(
f"Dataset {existing.table_name!r} (uuid {config['uuid']}) "
"already exists and user doesn't have permissions to "
"restore it"
)
# Before clearing ``deleted_at``, refuse if another active datasetView on GitHub (pinned to f4587218dd)
Solutions
- Grant the importing user/role the can_write dataset permission (or the can_import permission set) and retry — the restore path then runs with proper editorship checks
- Have an admin restore the soft-deleted dataset first, then import
- Remove the dataset from the bundle if the restore is not intended
Defensive patterns
Strategy: try-catch
Validate before calling
from superset.daos.dataset import DatasetDAO
from superset.models.slice import Slice # not needed; illustration of pre-check
# pre-check: does the uuid match a soft-deleted row, and can we write?
existing = find_existing_for_import(SqlaTable, config['uuid'])
if existing is not None and existing.deleted_at is not None:
assert current_user_has_dataset_write(), 're-import of a deleted dataset requires can_write' Try / catch
from superset.commands.exceptions import ImportFailedError
try:
import_dataset(config, overwrite=True)
except ImportFailedError as ex:
if 'requires can_write permission to restore it' in str(ex):
# elevate/grant permission or drop the dataset from the bundle; do not retry unchanged
... Prevention
- Run imports under a role with dataset write permission when restores are expected
- Check the bundle's UUIDs against existing/trashed datasets before import
- Clean up trash rows (restore or purge) before re-importing old bundles
When it happens
Trigger: Importing a bundle whose dataset UUID matches a dataset in the trash, via a REST import by a user without can_write permission on datasets (and not ignore_permissions).
Common situations: A user re-imports an old export after the dataset was soft-deleted; batch import scripts running under a read-mostly role; importing a dashboard bundle that embeds the deleted dataset's UUID.
Related errors
- Dataset {existing.table_name!r} (uuid {config['uuid']}) alre
- Dataset doesn't exist and user doesn't have permission to cr
- You don't have access to this dataset.
- Dataset {existing.table_name!r} (uuid {config['uuid']}) cann
- Dataset {existing.table_name!r} (uuid {config['uuid']}) alre
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/80109d9e95d1dbc0.
Report an issue: GitHub.