apache/superset · error · DatasourceNotFoundValidationError
Datasource does not exist
Error message
Datasource does not exist
What it means
DatasourceNotFoundValidationError is raised in CreateRLSRuleCommand.validate when the number of SqlaTable rows matching self._tables does not equal len(self._tables): at least one requested table/dataset id does not exist. Datasource checks run before name-uniqueness so callers cannot probe rule names of datasources they cannot access.
Source
Thrown at superset/commands/security/create.py:70
# The preflight uniqueness check in ``validate`` isn't atomic with
# this insert, so fall back to the database's unique constraint
# and translate it into the same descriptive validation error.
raise ValidationError(
{"name": [_("A rule with this name already exists.")]}
) from ex
return new_model
def validate(self) -> None:
# Datasource existence/access is validated before revealing whether
# the requested name is already in use, so an unauthorized caller
# can't use the duplicate-name response to enumerate rule names.
tables = (
db.session.query(SqlaTable)
.filter(SqlaTable.id.in_(self._tables)) # type: ignore[attr-defined]
.all()
)
if len(tables) != len(self._tables):
raise DatasourceNotFoundValidationError()
raise_for_datasource_access(tables)
self._properties["tables"] = tables
name = self._properties.get("name")
if name and not RLSDAO.validate_uniqueness(name):
raise ValidationError(
{"name": [_("A rule with this name already exists.")]}
)
if (
self._properties.get("filter_type")
== RowLevelSecurityFilterType.REGULAR.value
and not self._subjects
):
raise ValidationError(
{"subjects": ["Regular RLS filters require at least one subject."]}
)
View on GitHub (pinned to f4587218dd)
Solutions
- Resolve datasets by name/uuid (GET /api/v1/dataset/) at runtime instead of hard-coding integer ids
- Remove or correct the stale id in the payload and retry the POST
- If the dataset was deleted, recreate it first, then create the RLS rule
Example fix
# before
payload['tables'] = [42] # deleted dataset id
# after
ds = client.get('/api/v1/dataset/?q=(table_name:eq:my_table)').json()['result'][0]
payload['tables'] = [ds['id']] Defensive patterns
Strategy: validation
Validate before calling
known = {d['id'] for d in client.get('/api/v1/dataset/').json()['result']}
assert set(table_ids) <= known, f'unknown dataset ids: {set(table_ids) - known}' Try / catch
from superset.commands.exceptions import DatasourceNotFoundValidationError
try:
CreateRLSRuleCommand(props).run()
except DatasourceNotFoundValidationError:
table_ids = resolve_dataset_ids_by_name(props['tables'])
CreateRLSRuleCommand({**props, 'tables': table_ids}).run() Prevention
- Resolve dataset ids from names/uuids at request time
- Fail fast in scripts when a referenced dataset is missing
- Never copy integer dataset ids between environments
When it happens
Trigger: POST /api/v1/rowlevelsecurity with a 'tables' array containing a dataset id that was deleted, belongs to another environment, or is simply mistyped.
Common situations: Hard-coded dataset ids in provisioning scripts after a metadata DB reset; datasets refreshed/recreated with new ids; copying an RLS rule definition between staging and production where ids differ.
Related errors
- Datasource does not exist
- Datasource does not exist
- Dashboard %(dashboard_id)s not found
- Annotation layer not found.
- Database not found.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/d1a4efa1c2899e2d.
Report an issue: GitHub.