apache/superset · error · DatasetSoftDeletedTwinExistsError

A soft-deleted dataset (uuid %(uuid)s) already references th

Error message

A soft-deleted dataset (uuid %(uuid)s) already references this table. Restore it via POST /api/v1/dataset/%(uuid)s/restore before creating a new dataset over this table, or use a different table name.

What it means

DatasetSoftDeletedTwinExistsError (HTTP 422) is raised by the dataset create command when uniqueness validation fails and DatasetDAO.find_soft_deleted_logical_duplicate finds a soft-deleted dataset referencing the same physical table (database/catalog/schema/table). The message names the twin's uuid and points at POST /api/v1/dataset/<uuid>/restore. It exists to disambiguate the confusing case where the dataset list 'looks empty' (soft-deleted rows are hidden) but the create still collides.

Source

Thrown at superset/commands/dataset/create.py:85

            exceptions.append(DatabaseNotFoundValidationError())
        self._properties["database"] = database

        # Validate uniqueness
        if database:
            if not catalog:
                catalog = self._properties["catalog"] = database.get_default_catalog()

            table = Table(table_name, schema, catalog)

            if not DatasetDAO.validate_uniqueness(database, table):
                # Distinguish the hidden-twin case: uniqueness fails while
                # the caller's dataset list looks empty. Raise the targeted
                # 422 (naming the twin's uuid and the restore endpoint)
                # instead of the opaque "already exists".
                if soft_twin := DatasetDAO.find_soft_deleted_logical_duplicate(
                    database, table
                ):
                    raise DatasetSoftDeletedTwinExistsError(str(soft_twin.uuid))
                exceptions.append(DatasetExistsValidationError(table))

        # Validate table exists on dataset if sql is not provided
        # This should be validated when the dataset is physical
        if (
            database
            and not sql
            and not DatasetDAO.validate_table_exists(database, table)
        ):
            exceptions.append(TableNotFoundValidationError(table))

        if sql:
            try:
                security_manager.raise_for_access(
                    database=database,
                    sql=sql,
                    catalog=catalog,
                    schema=schema,

View on GitHub (pinned to f4587218dd)

Solutions

  1. Restore the twin using the uuid from the message: POST /api/v1/dataset/<uuid>/restore — this makes the original dataset active again.
  2. If you truly want a brand-new dataset, hard-delete the soft-deleted row (admin/CLI purge) or create the dataset over a different table name.
  3. Do not retry the same create — the collision is deterministic until the twin is restored or purged.

Example fix

# before
POST /api/v1/dataset/ {"database": 1, "table_name": "sales"}
# -> 422 soft-deleted twin (uuid abc-...) exists

# after
curl -X POST /api/v1/dataset/abc-.../restore
# then edit the restored dataset instead of creating a new one
Defensive patterns

Strategy: fallback

Validate before calling

# Detect a soft-deleted twin before creating
from superset.daos.dataset import DatasetDAO
from superset.connectors.sqla.models import Table

def soft_twin_uuid(database, table_name: str, schema=None, catalog=None):
    twin = DatasetDAO.find_soft_deleted_logical_duplicate(
        database, Table(table_name, schema, catalog)
    )
    return str(twin.uuid) if twin else None

Try / catch

from superset.commands.dataset.exceptions import DatasetSoftDeletedTwinExistsError
import re
try:
    CreateDatasetCommand(properties).run()
except DatasetSoftDeletedTwinExistsError as ex:
    uuid = re.search(
        r"uuid ([0-9a-f-]{36})", str(ex)
    ).group(1)
    restore_dataset(uuid)  # fallback path: restore the twin instead of creating

Prevention

When it happens

Trigger: POST /api/v1/dataset/ for a table whose dataset was previously soft-deleted (UI delete keeps the row with deleted_at set); recreating a dataset over a table that a deleted dashboard/dataset import claimed; the same physical table targeted after a delete-then-recreate cycle.

Common situations: Teams deleting a dataset to 'recreate it fresh' and hitting an invisible collision; soft-deleted rows accumulating after many experiments; restores attempted while a duplicate still exists.

Related errors


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