{"record":{"id":"396fa6bb4c58dc5b","repo":"apache/superset","slug":"dataset-does-not-exist","errorCode":null,"errorMessage":"Dataset does not exist","messagePattern":"Dataset does not exist","errorType":"http","errorClass":"DatasetNotFoundError","httpStatus":404,"severity":"error","filePath":"superset/commands/dataset/delete.py","lineNumber":51,"sourceCode":"logger = logging.getLogger(__name__)\n\n\nclass DeleteDatasetCommand(BaseCommand):\n    def __init__(self, model_ids: list[int]):\n        self._model_ids = model_ids\n        self._models: Optional[list[SqlaTable]] = None\n\n    @transaction(on_error=partial(on_error, reraise=DatasetDeleteFailedError))\n    def run(self) -> None:\n        self.validate()\n        assert self._models\n        DatasetDAO.delete(self._models)\n\n    def validate(self) -> None:\n        # Validate/populate model exists\n        self._models = DatasetDAO.find_by_ids(self._model_ids)\n        if not self._models or len(self._models) != len(self._model_ids):\n            raise DatasetNotFoundError()\n        # Check editorship\n        for model in self._models:\n            try:\n                security_manager.raise_for_editorship(model)\n            except SupersetSecurityException as ex:\n                raise DatasetForbiddenError() from ex\n","sourceCodeStart":33,"sourceCodeEnd":58,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dataset/delete.py#L33-L58","documentation":"DatasetNotFoundError (HTTP 404, 'Dataset does not exist') is raised by the bulk dataset delete command when DatasetDAO.find_by_ids returns fewer models than requested ids — i.e., at least one id in the DELETE payload does not exist. The command is all-or-nothing: one missing id fails the whole request before any deletion happens.","triggerScenarios":"DELETE /api/v1/dataset/ with body {\"q\": \"(id:1,999)\"} where 999 doesn't exist; datasets deleted by another user between selection and bulk delete; ids from a different environment's metadata DB.","commonSituations":"Bulk-cleaning scripts with hardcoded id lists; UI multi-select over stale data; concurrent deletes by two admins.","solutions":["Resolve which ids are missing (GET /api/v1/dataset/?q=(id:...) or compare against the list endpoint) and retry with only existing ids.","For idempotent cleanup, treat 404 on specific ids as 'already deleted' and continue with the rest.","In scripts, look ids up by uuid or name at runtime instead of persisting integer ids."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Filter the bulk-delete id list down to existing datasets\nfrom superset.daos.dataset import DatasetDAO\n\ndef existing_dataset_ids(ids: list[int]) -> list[int]:\n    found = {d.id for d in (DatasetDAO.find_by_ids(ids) or [])}\n    return [i for i in ids if i in found]","typeGuard":null,"tryCatchPattern":"from superset.commands.dataset.exceptions import DatasetNotFoundError\ntry:\n    DeleteDatasetsCommand(ids).run()\nexcept DatasetNotFoundError:\n    # all-or-nothing failed: retry with only the ids that still exist\n    DeleteDatasetsCommand(existing_dataset_ids(ids)).run()","preventionTips":["Re-resolve ids immediately before bulk operations; expect concurrent deletes.","Design bulk flows to shrink the id set on 404 rather than abort the batch.","Reference datasets by uuid in persisted scripts, resolving ids per run."],"tags":["dataset","not-found","bulk-delete","flask-api"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}