{"record":{"id":"c619aca846d95a7e","repo":"apache/superset","slug":"dataset-config-table-name-r-cannot-be-importe","errorCode":null,"errorMessage":"Dataset {config['table_name']!r} cannot be imported because a soft-deleted dataset (uuid {soft_twin.uuid}) already references the same physical table; restore that dataset instead of importing a duplicate","messagePattern":"Dataset (.+?) cannot be imported because a soft-deleted dataset \\(uuid (.+?)\\) already references the same physical table; restore that dataset instead of importing a duplicate","errorType":"exception","errorClass":"ImportFailedError","httpStatus":500,"severity":"error","filePath":"superset/commands/dataset/importers/v1/utils.py","lineNumber":401,"sourceCode":"        # 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`` —\n        # mirror it here and direct the user to restore the existing dataset\n        # instead of leaving two rows for one physical table.\n        database = (\n            db.session.query(Database).filter_by(id=config[\"database_id\"]).first()\n        )\n        if database is not None and (\n            soft_twin := DatasetDAO.find_soft_deleted_logical_duplicate(\n                database,\n                Table(\n                    config[\"table_name\"], config.get(\"schema\"), config.get(\"catalog\")\n                ),\n            )\n        ):\n            raise ImportFailedError(\n                f\"Dataset {config['table_name']!r} cannot be imported because \"\n                f\"a soft-deleted dataset (uuid {soft_twin.uuid}) already \"\n                \"references the same physical table; restore that dataset \"\n                \"instead of importing a duplicate\"\n            )\n\n    # Trusted imports (e.g. example loading) carry curated configs; only\n    # untrusted user imports validate the catalog, like the access checks below.\n    if not ignore_permissions:\n        validate_catalog(config)\n\n    # TODO (betodealmeida): move this logic to import_from_dict\n    config = config.copy()\n    for key in JSON_KEYS:\n        if config.get(key) is not None:\n            try:\n                config[key] = json.dumps(config[key])\n            except TypeError:","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dataset/importers/v1/utils.py#L383-L419","documentation":"When creating a brand-new dataset from an import, the code queries DatasetDAO.find_soft_deleted_logical_duplicate for the config's physical identity. Because import_from_dict's visibility filter hides soft-deleted rows, without this guard the import would create an active twin of a hidden (trashed) dataset; the guard mirrors the REST create path's validate_uniqueness and refuses with a message pointing at the soft-deleted twin's UUID.","triggerScenarios":"Importing a dataset whose database+schema+table (and catalog) match a dataset currently in the soft-delete trash — e.g. re-importing an export after the dataset was soft-deleted under a different UUID, or after deletion removed the UUID linkage.","commonSituations":"Delete-then-reimport workflows where the trash still holds the row; exports regenerated without the original UUID so the UUID-match restore path never triggers.","solutions":["Restore the soft-deleted dataset (its uuid is named in the error) via the restore endpoint or an import carrying that UUID, instead of creating a duplicate","Purge the soft-deleted row permanently, then retry the import","Rename the uploaded table_name/schema so it no longer collides"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from superset.daos.dataset import DatasetDAO\n\ndatabase = session.query(Database).filter_by(id=config['database_id']).first()\nsoft_twin = DatasetDAO.find_soft_deleted_logical_duplicate(\n    database, Table(config['table_name'], config.get('schema'), config.get('catalog'))\n)\nif soft_twin is not None:\n    # restore the twin instead of importing a duplicate\n    ...","typeGuard":null,"tryCatchPattern":"from superset.commands.exceptions import ImportFailedError\ntry:\n    import_dataset(config)\nexcept ImportFailedError as ex:\n    if 'soft-deleted dataset' in str(ex) and 'restore that dataset' in str(ex):\n        # restore the named uuid via the restore endpoint instead of re-importing\n        ...","preventionTips":["Preserve original UUIDs when re-exporting bundles so the restore path matches","Restore from trash instead of re-importing when possible","Purge trash rows before bulk-creating datasets with reused identities"],"tags":["dataset-import","uniqueness","soft-delete","conflict","superset"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}