{"record":{"id":"39fd4b0fecd87f59","repo":"apache/superset","slug":"dataset-existing-table-name-r-uuid-config-uui-39fd4b","errorCode":null,"errorMessage":"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.","messagePattern":"Dataset (.+?) \\(uuid (.+?)\\) cannot be overwritten: another dataset \\(possibly soft-deleted\\) already references the target table \\((.+?)\\)\\. Restore or rename the other dataset, or change this upload's table name\\.","errorType":"exception","errorClass":"ImportFailedError","httpStatus":500,"severity":"error","filePath":"superset/commands/dataset/importers/v1/utils.py","lineNumber":369,"sourceCode":"                )\n            # Mirror the REST update path's uniqueness contract: the uploaded\n            # config may rename this dataset onto the physical identity of a\n            # soft-deleted twin. ``import_from_dict``'s lookup cannot see the\n            # hidden row (visibility filter), so without this check the\n            # update would land cleanly and the live row would silently squat\n            # the trash row's identity — permanently 422-blocking its\n            # restore. ``validate_update_uniqueness`` bypasses the filter by\n            # design, so hidden twins block here exactly as they block\n            # ``UpdateDatasetCommand``.\n            overwrite_identity = Table(\n                config.get(\"table_name\") or existing.table_name,\n                config.get(\"schema\", existing.schema),\n                config.get(\"catalog\", existing.catalog),\n            )\n            if not DatasetDAO.validate_update_uniqueness(\n                existing.database, overwrite_identity, dataset_id=existing.id\n            ):\n                raise ImportFailedError(\n                    f\"Dataset {existing.table_name!r} (uuid {config['uuid']}) \"\n                    \"cannot be overwritten: another dataset (possibly \"\n                    \"soft-deleted) already references the target table \"\n                    f\"({overwrite_identity.table!r}). Restore or rename the \"\n                    \"other dataset, or change this upload's table name.\"\n                )\n            config[\"id\"] = existing.id\n\n    elif not can_write:\n        raise ImportFailedError(\n            \"Dataset doesn't exist and user doesn't have permission to create datasets\"\n        )\n    else:\n        # Creating a brand-new dataset (no UUID match). A soft-deleted dataset\n        # may still claim this physical table; ``import_from_dict`` cannot see it\n        # (the visibility filter hides soft-deleted rows), so without this guard\n        # the import would create an active twin of a hidden dataset. The REST\n        # create path blocks the same collision via ``validate_uniqueness`` —","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dataset/importers/v1/utils.py#L351-L387","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Change table_name/schema/catalog in the uploaded YAML so the post-overwrite identity is unique","Restore or purge the other (possibly soft-deleted) dataset that claims the identity, then retry","Rename the conflicting dataset via the UI/API before importing"],"exampleFix":"# before (YAML rename onto an occupied name)\ntable_name: revenue\n# after\ntable_name: revenue_v2","handlingStrategy":"validation","validationCode":"from superset.daos.dataset import DatasetDAO\n\noverwrite_identity = Table(\n    config.get('table_name'), config.get('schema'), config.get('catalog')\n)\nif not DatasetDAO.validate_update_uniqueness(\n    existing.database, overwrite_identity, dataset_id=existing.id\n):\n    raise ValueError('target identity claimed by another (possibly soft-deleted) dataset')","typeGuard":null,"tryCatchPattern":"from superset.commands.exceptions import ImportFailedError\ntry:\n    import_dataset(config, overwrite=True)\nexcept ImportFailedError as ex:\n    if 'another dataset (possibly soft-deleted) already references the target table' in str(ex):\n        # purge/restore the claimant or change table_name; then retry once\n        ...","preventionTips":["Purge (not just soft-delete) datasets whose identities will be reused","Check identity uniqueness (including trash) before rename-by-import","Keep one canonical dataset per physical table"],"tags":["dataset-import","uniqueness","overwrite","soft-delete","conflict","superset"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}