{"record":{"id":"d1a4efa1c2899e2d","repo":"apache/superset","slug":"datasource-does-not-exist","errorCode":null,"errorMessage":"Datasource does not exist","messagePattern":"Datasource does not exist","errorType":"validation","errorClass":"DatasourceNotFoundValidationError","httpStatus":404,"severity":"error","filePath":"superset/commands/security/create.py","lineNumber":70,"sourceCode":"            # The preflight uniqueness check in ``validate`` isn't atomic with\n            # this insert, so fall back to the database's unique constraint\n            # and translate it into the same descriptive validation error.\n            raise ValidationError(\n                {\"name\": [_(\"A rule with this name already exists.\")]}\n            ) from ex\n        return new_model\n\n    def validate(self) -> None:\n        # Datasource existence/access is validated before revealing whether\n        # the requested name is already in use, so an unauthorized caller\n        # can't use the duplicate-name response to enumerate rule names.\n        tables = (\n            db.session.query(SqlaTable)\n            .filter(SqlaTable.id.in_(self._tables))  # type: ignore[attr-defined]\n            .all()\n        )\n        if len(tables) != len(self._tables):\n            raise DatasourceNotFoundValidationError()\n        raise_for_datasource_access(tables)\n        self._properties[\"tables\"] = tables\n\n        name = self._properties.get(\"name\")\n        if name and not RLSDAO.validate_uniqueness(name):\n            raise ValidationError(\n                {\"name\": [_(\"A rule with this name already exists.\")]}\n            )\n\n        if (\n            self._properties.get(\"filter_type\")\n            == RowLevelSecurityFilterType.REGULAR.value\n            and not self._subjects\n        ):\n            raise ValidationError(\n                {\"subjects\": [\"Regular RLS filters require at least one subject.\"]}\n            )\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/security/create.py#L52-L88","documentation":"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.","triggerScenarios":"POST /api/v1/rowlevelsecurity with a 'tables' array containing a dataset id that was deleted, belongs to another environment, or is simply mistyped.","commonSituations":"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.","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"],"exampleFix":"# before\npayload['tables'] = [42]  # deleted dataset id\n\n# after\nds = client.get('/api/v1/dataset/?q=(table_name:eq:my_table)').json()['result'][0]\npayload['tables'] = [ds['id']]","handlingStrategy":"validation","validationCode":"known = {d['id'] for d in client.get('/api/v1/dataset/').json()['result']}\nassert set(table_ids) <= known, f'unknown dataset ids: {set(table_ids) - known}'","typeGuard":null,"tryCatchPattern":"from superset.commands.exceptions import DatasourceNotFoundValidationError\ntry:\n    CreateRLSRuleCommand(props).run()\nexcept DatasourceNotFoundValidationError:\n    table_ids = resolve_dataset_ids_by_name(props['tables'])\n    CreateRLSRuleCommand({**props, 'tables': table_ids}).run()","preventionTips":["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"],"tags":["rls","datasource","not-found","validation"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}