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
- Restore the twin using the uuid from the message: POST /api/v1/dataset/<uuid>/restore — this makes the original dataset active again.
- 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.
- 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
- Prefer restoring (POST /api/v1/dataset/<uuid>/restore) over delete-and-recreate cycles.
- When writing delete-then-create automation, hard-purge soft-deleted datasets or check find_soft_deleted_logical_duplicate first.
- Teach users that UI delete is soft: the physical table claim survives.
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
- Dataset cannot be restored because another active dataset al
- Chart {existing.slice_name!r} (uuid {config['uuid']}) was de
- Dashboard was deleted and re-import requires can_write permi
- A dashboard already exists and user doesn't have permissions
- 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/39dac60326011297.
Report an issue: GitHub.