apache/superset · error · ImportFailedError
Dataset {config['table_name']!r} cannot be imported because
Error message
Dataset {config['table_name']!r} cannot be imported because a soft-deleted dataset (uuid {soft_twin.uuid}) already references the same physical table; restore that dataset instead of importing a duplicate What it means
When creating a brand-new dataset from an import, the code queries DatasetDAO.find_soft_deleted_logical_duplicate for the config's physical identity. Because import_from_dict's visibility filter hides soft-deleted rows, without this guard the import would create an active twin of a hidden (trashed) dataset; the guard mirrors the REST create path's validate_uniqueness and refuses with a message pointing at the soft-deleted twin's UUID.
Source
Thrown at superset/commands/dataset/importers/v1/utils.py:401
# Creating a brand-new dataset (no UUID match). A soft-deleted dataset
# may still claim this physical table; ``import_from_dict`` cannot see it
# (the visibility filter hides soft-deleted rows), so without this guard
# the import would create an active twin of a hidden dataset. The REST
# create path blocks the same collision via ``validate_uniqueness`` —
# mirror it here and direct the user to restore the existing dataset
# instead of leaving two rows for one physical table.
database = (
db.session.query(Database).filter_by(id=config["database_id"]).first()
)
if database is not None and (
soft_twin := DatasetDAO.find_soft_deleted_logical_duplicate(
database,
Table(
config["table_name"], config.get("schema"), config.get("catalog")
),
)
):
raise ImportFailedError(
f"Dataset {config['table_name']!r} cannot be imported because "
f"a soft-deleted dataset (uuid {soft_twin.uuid}) already "
"references the same physical table; restore that dataset "
"instead of importing a duplicate"
)
# Trusted imports (e.g. example loading) carry curated configs; only
# untrusted user imports validate the catalog, like the access checks below.
if not ignore_permissions:
validate_catalog(config)
# TODO (betodealmeida): move this logic to import_from_dict
config = config.copy()
for key in JSON_KEYS:
if config.get(key) is not None:
try:
config[key] = json.dumps(config[key])
except TypeError:View on GitHub (pinned to f4587218dd)
Solutions
- Restore the soft-deleted dataset (its uuid is named in the error) via the restore endpoint or an import carrying that UUID, instead of creating a duplicate
- Purge the soft-deleted row permanently, then retry the import
- Rename the uploaded table_name/schema so it no longer collides
Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.dataset import DatasetDAO
database = session.query(Database).filter_by(id=config['database_id']).first()
soft_twin = DatasetDAO.find_soft_deleted_logical_duplicate(
database, Table(config['table_name'], config.get('schema'), config.get('catalog'))
)
if soft_twin is not None:
# restore the twin instead of importing a duplicate
... Try / catch
from superset.commands.exceptions import ImportFailedError
try:
import_dataset(config)
except ImportFailedError as ex:
if 'soft-deleted dataset' in str(ex) and 'restore that dataset' in str(ex):
# restore the named uuid via the restore endpoint instead of re-importing
... Prevention
- Preserve original UUIDs when re-exporting bundles so the restore path matches
- Restore from trash instead of re-importing when possible
- Purge trash rows before bulk-creating datasets with reused identities
When it happens
Trigger: Importing a dataset whose database+schema+table (and catalog) match a dataset currently in the soft-delete trash — e.g. re-importing an export after the dataset was soft-deleted under a different UUID, or after deletion removed the UUID linkage.
Common situations: Delete-then-reimport workflows where the trash still holds the row; exports regenerated without the original UUID so the UUID-match restore path never triggers.
Related errors
- Dataset {existing.table_name!r} (uuid {config['uuid']}) cann
- Dataset {existing.table_name!r} (uuid {config['uuid']}) cann
- Dataset {existing.table_name!r} (uuid {config['uuid']}) was
- Dataset {existing.table_name!r} (uuid {config['uuid']}) alre
- Dashboard cannot be restored because its slug is now used by
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/c619aca846d95a7e.
Report an issue: GitHub.