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 overwritten: another dataset (possibly soft-deleted) already references the target table ({overwrite_identity.table!r}). Restore or rename the other dataset, or change this upload's table name.

What it means

Before overwriting a live dataset, the import mirrors the REST update-path uniqueness contract: it builds the post-update identity (table_name/schema/catalog from the config) and calls DatasetDAO.validate_update_uniqueness. If another dataset — possibly soft-deleted, which the normal import lookup cannot see — already claims that physical table, the overwrite is refused. Without this check a live row could silently squat a trash row's identity and permanently block that row's restore with 422s.

Source

Thrown at superset/commands/dataset/importers/v1/utils.py:369

                )
            # Mirror the REST update path's uniqueness contract: the uploaded
            # config may rename this dataset onto the physical identity of a
            # soft-deleted twin. ``import_from_dict``'s lookup cannot see the
            # hidden row (visibility filter), so without this check the
            # update would land cleanly and the live row would silently squat
            # the trash row's identity — permanently 422-blocking its
            # restore. ``validate_update_uniqueness`` bypasses the filter by
            # design, so hidden twins block here exactly as they block
            # ``UpdateDatasetCommand``.
            overwrite_identity = Table(
                config.get("table_name") or existing.table_name,
                config.get("schema", existing.schema),
                config.get("catalog", existing.catalog),
            )
            if not DatasetDAO.validate_update_uniqueness(
                existing.database, overwrite_identity, dataset_id=existing.id
            ):
                raise ImportFailedError(
                    f"Dataset {existing.table_name!r} (uuid {config['uuid']}) "
                    "cannot be overwritten: another dataset (possibly "
                    "soft-deleted) already references the target table "
                    f"({overwrite_identity.table!r}). Restore or rename the "
                    "other dataset, or change this upload's table name."
                )
            config["id"] = existing.id

    elif not can_write:
        raise ImportFailedError(
            "Dataset doesn't exist and user doesn't have permission to create datasets"
        )
    else:
        # 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`` —

View on GitHub (pinned to f4587218dd)

Solutions

  1. Change table_name/schema/catalog in the uploaded YAML so the post-overwrite identity is unique
  2. Restore or purge the other (possibly soft-deleted) dataset that claims the identity, then retry
  3. Rename the conflicting dataset via the UI/API before importing

Example fix

# before (YAML rename onto an occupied name)
table_name: revenue
# after
table_name: revenue_v2
Defensive patterns

Strategy: validation

Validate before calling

from superset.daos.dataset import DatasetDAO

overwrite_identity = Table(
    config.get('table_name'), config.get('schema'), config.get('catalog')
)
if not DatasetDAO.validate_update_uniqueness(
    existing.database, overwrite_identity, dataset_id=existing.id
):
    raise ValueError('target identity claimed by another (possibly soft-deleted) dataset')

Try / catch

from superset.commands.exceptions import ImportFailedError
try:
    import_dataset(config, overwrite=True)
except ImportFailedError as ex:
    if 'another dataset (possibly soft-deleted) already references the target table' in str(ex):
        # purge/restore the claimant or change table_name; then retry once
        ...

Prevention

When it happens

Trigger: Importing with overwrite where the uploaded YAML renames the dataset onto a physical identity claimed by another dataset (including one sitting in the soft-delete trash), or onto an identity identical to an existing twin row.

Common situations: Re-importing a renamed export after a same-named dataset was soft-deleted; cleanup attempts that soft-delete rather than purge leave hidden claimants of the table name.

Related errors


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