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 modelView on GitHub (pinned to f4587218dd)
Solutions
- Verify existence first: GET /api/v1/dataset/{id} (and GET /api/v1/dataset/?q=(id:eq:{id}) for filtered environments).
- If soft-deleted, restore the row before updating.
- Prefer addressing datasets by UUID in automation instead of integer ids to survive cross-environment drift.
- 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
- Prefer UUID-keyed lookups over integer ids in pipelines.
- GET before PUT in write paths.
- Handle delete/create races by re-resolving instead of crashing.
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
- Dataset does not exist
- Dataset parameters are invalid.
- The provided table was not found in the provided database
- Dashboard %(dashboard_id)s not found
- Annotation layer not found.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/4734eb68881c00ed.
Report an issue: GitHub.