{"record":{"id":"5003f9e55af90856","repo":"apache/superset","slug":"dataset-existing-table-name-r-uuid-config-uui-5003f9","errorCode":null,"errorMessage":"Dataset {existing.table_name!r} (uuid {config['uuid']}) already exists and user doesn't have permissions to overwrite it","messagePattern":"Dataset (.+?) \\(uuid (.+?)\\) already exists and user doesn't have permissions to overwrite it","errorType":"exception","errorClass":"ImportFailedError","httpStatus":500,"severity":"error","filePath":"superset/commands/dataset/importers/v1/utils.py","lineNumber":347,"sourceCode":"            # ``MultipleResultsFound`` fallback. Without the rollback, an\n            # ambiguous import would leave the dataset half-restored\n            # (``deleted_at = None`` but upload contents unapplied).\n            original_deleted_at = existing.deleted_at\n            existing.restore()\n            db.session.flush()\n            is_soft_deleted_match = True\n            config[\"id\"] = existing.id\n        else:\n            # OVERWRITE path — existing alive row. Without ``overwrite`` or\n            # write permission, return it unchanged (the pre-soft-delete\n            # overwrite-without-permission behaviour).\n            if not overwrite or not can_write:\n                return existing\n            if user and (\n                not security_manager.is_editor(existing)\n                and not security_manager.is_admin()\n            ):\n                raise ImportFailedError(\n                    f\"Dataset {existing.table_name!r} (uuid {config['uuid']}) \"\n                    \"already exists and user doesn't have permissions to \"\n                    \"overwrite it\"\n                )\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            )","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dataset/importers/v1/utils.py#L329-L365","documentation":"On the overwrite path (UUID matches a live dataset), if overwrite=True and can_write hold but the current user is neither an editor/owner of that dataset nor an admin, ImportFailedError is raised. It blocks users who can import in general from clobbering datasets they do not own.","triggerScenarios":"POST /api/v1/dataset/import with overwrite=true where the UUID matches a live dataset owned by others and the importing user is not an owner/editor/admin.","commonSituations":"Shared workspaces: one team imports a bundle that happens to carry another team's dataset UUID; CI re-imports under a service account that lacks ownership of pre-existing datasets.","solutions":["Add the importing user (or service account) as an owner of the target dataset, then retry","Run the import as an admin","Import without overwrite if the existing dataset should stay untouched"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"from superset import security_manager\nexisting = find_existing_for_import(SqlaTable, config['uuid'])\nif existing is not None and existing.deleted_at is None and overwrite:\n    user = security_manager.get_current_user()\n    if user and not (security_manager.is_editor(existing) or security_manager.is_admin()):\n        raise PermissionError('importing user must own the target dataset to overwrite it')","typeGuard":null,"tryCatchPattern":"from superset.commands.exceptions import ImportFailedError\ntry:\n    import_dataset(config, overwrite=True)\nexcept ImportFailedError as ex:\n    if \"doesn't have permissions to overwrite it\" in str(ex):\n        # add user as owner of the dataset, or import without overwrite; no blind retry\n        ...","preventionTips":["Add CI service accounts as owners of datasets they re-import","Import without overwrite when you only need existence","Scope bundles per team so UUIDs don't cross ownership boundaries"],"tags":["dataset-import","permissions","ownership","overwrite","superset"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}