apache/superset · error · ImportFailedError
Dataset {existing.table_name!r} (uuid {config['uuid']}) cann
Error message
Dataset {existing.table_name!r} (uuid {config['uuid']}) cannot be restored via re-import because another active dataset already references the same physical table ({incoming_identity.table!r}). Rename one of them and retry. What it means
Before clearing deleted_at on restore, the import checks DatasetDAO.has_active_logical_duplicate against the post-update physical identity (table_name/schema/catalog from the uploaded config, falling back to stored values). If another active dataset row already references the same physical table, the restore is refused so there are never two live SqlaTable rows for one physical table.
Source
Thrown at superset/commands/dataset/importers/v1/utils.py:298
# already references the same physical table. Otherwise the
# restore would produce two live ``SqlaTable`` rows for one
# physical table, breaking the logical-uniqueness contract. The
# shared DAO helper relies on the SoftDeleteMixin listener to
# consider only active rows, excludes ``existing`` itself via
# ``id !=``, and normalizes the catalog the same way create/update
# uniqueness does.
# Probe the POST-update identity: the uploaded config may rename
# table_name/schema/catalog, and the collision that matters is
# against the identity the restored row will end up with — not
# the stale stored one. Absent keys fall back to the stored
# values; explicit nulls are respected.
incoming_identity = Table(
config.get("table_name") or existing.table_name,
config.get("schema", existing.schema),
config.get("catalog", existing.catalog),
)
if DatasetDAO.has_active_logical_duplicate(existing, incoming_identity):
raise ImportFailedError(
f"Dataset {existing.table_name!r} (uuid {config['uuid']}) "
"cannot be restored via re-import because another active "
"dataset already references the same physical table "
f"({incoming_identity.table!r}). Rename one of them and "
"retry."
)
# Restore in place (clear ``deleted_at``) rather than
# hard-delete-and-replace: a hard delete would cascade through the
# chart back-reference and the delete-orphan child relationships
# (table_columns, sql_metrics), which the import would then need to
# reconstruct.
#
# How the restore lands as an UPDATE: clearing
# ``existing.deleted_at`` marks the in-session row dirty and the
# explicit flush emits the ``deleted_at = NULL`` UPDATE before
# ``SqlaTable.import_from_dict`` (below) does its own query-by-uuid
# lookup. Without the flush we would be relying on autoflush ahead
# of that internal query — correct under default session config butView on GitHub (pinned to f4587218dd)
Solutions
- Rename the table_name/schema/catalog in the uploaded YAML to an unoccupied identity and retry
- Rename or soft-delete the other active dataset that now owns the physical table, then retry the import
- Restore the newer dataset instead of re-importing the old one
Example fix
# before (YAML) table_name: sales schema: public # after (avoid the collision) table_name: sales_restored schema: public
Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.dataset import DatasetDAO
from superset.models.helpers import Table # identity namedtuple pattern
incoming = Table(config.get('table_name'), config.get('schema'), config.get('catalog'))
existing = find_existing_for_import(SqlaTable, config['uuid'])
if existing is not None and existing.deleted_at is not None:
if DatasetDAO.has_active_logical_duplicate(existing, incoming):
raise ValueError(f'identity {incoming} already taken by an active dataset — rename first') Try / catch
from superset.commands.exceptions import ImportFailedError
try:
import_dataset(config)
except ImportFailedError as ex:
if 'another active dataset already references the same physical table' in str(ex):
config['table_name'] += '_imported' # disambiguate and retry once
import_dataset(config) Prevention
- Avoid deleting-then-recreating datasets with the same physical identity
- When renaming datasets, check the target identity is free (including trash)
- Adopt a naming convention for restored datasets
When it happens
Trigger: Importing a bundle to restore a soft-deleted dataset while another dataset (created after the deletion) already occupies the same database+schema+table (or catalog) identity — including when the upload renames the dataset onto an occupied identity.
Common situations: Dataset deleted, a new one created with the same table, then an old export is re-imported; uploads that change table_name/schema in the YAML colliding with an existing live dataset.
Related errors
- Dataset {existing.table_name!r} (uuid {config['uuid']}) cann
- Dataset {config['table_name']!r} cannot be imported because
- 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/5e18023565702e1f.
Report an issue: GitHub.