apache/superset · error · DatasetNotFoundError

Dataset does not exist

Error message

Dataset does not exist

What it means

DatasetNotFoundError is raised by UpdateDatasetCommand.validate() when DatasetDAO.find_by_id(self._model_id) returns None before any property changes are applied. The update endpoint maps it to HTTP 404.

Source

Thrown at superset/commands/dataset/update.py:105

            catches=(
                SQLAlchemyError,
                ValueError,
            ),
            reraise=DatasetUpdateFailedError,
        )
    )
    def run(self) -> Model:
        self.validate()
        assert self._model
        return DatasetDAO.update(self._model, attributes=self._properties)

    def validate(self) -> None:
        exceptions: list[ValidationError] = []

        # Validate/populate model exists
        self._model = DatasetDAO.find_by_id(self._model_id)
        if not self._model:
            raise DatasetNotFoundError()

        # Check permission to update the dataset
        try:
            security_manager.raise_for_editorship(self._model)
        except SupersetSecurityException as ex:
            raise DatasetForbiddenError() from ex

        # Validate/Populate editors
        compute_subjects(self._model, self._properties, exceptions)

        self._validate_dataset_source(exceptions)
        self._validate_semantics(exceptions)

        if exceptions:
            raise DatasetInvalidError(exceptions=exceptions)

    def _validate_dataset_source(self, exceptions: list[ValidationError]) -> None:
        # we know we have a valid model

View on GitHub (pinned to f4587218dd)

Solutions

  1. Verify existence first: GET /api/v1/dataset/{id} (and GET /api/v1/dataset/?q=(id:eq:{id}) for filtered environments).
  2. If soft-deleted, restore the row before updating.
  3. Prefer addressing datasets by UUID in automation instead of integer ids to survive cross-environment drift.
  4. Re-fetch the id list right before bulk updates rather than caching it.

Example fix

# before
client.put(f"/api/v1/dataset/{dataset_id}", json=props)  # 404

# after
resp = client.get(f"/api/v1/dataset/{dataset_id}")
if resp.status_code == 404:
    dataset_id = find_dataset_by_uuid(client, dataset_uuid)
client.put(f"/api/v1/dataset/{dataset_id}", json=props)
Defensive patterns

Strategy: validation

Validate before calling

resp = client.get(f"/api/v1/dataset/{dataset_id}")
if resp.status_code == 404:
    dataset_id = resolve_dataset_by_uuid(client, dataset_uuid)

Try / catch

try:
    UpdateDatasetCommand(user, model_id, properties).run()
except DatasetNotFoundError:
    refresh_id_cache()  # then retry once with the resolved id

Prevention

When it happens

Trigger: PUT/PATCH /api/v1/dataset/{id} where id does not exist, was hard-deleted, or is soft-deleted and hidden by DAO filters. Also occurs when a batch update payload contains a stale id.

Common situations: Configuration-as-code pipelines (yaml/json exports) applied to an environment where dataset ids differ. Races where another process deletes the dataset between a GET and the PUT. Ids taken from an exported YAML that used a different metadata DB.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/4734eb68881c00ed. Report an issue: GitHub.