{"record":{"id":"08830cb3e095d74a","repo":"apache/superset","slug":"changing-this-dataset-is-forbidden-08830c","errorCode":null,"errorMessage":"Changing this dataset is forbidden","messagePattern":"Changing this dataset is forbidden","errorType":"exception","errorClass":"DatasetForbiddenError","httpStatus":403,"severity":"error","filePath":"superset/commands/dataset/update.py","lineNumber":111,"sourceCode":"    )\n    def run(self) -> Model:\n        self.validate()\n        assert self._model\n        return DatasetDAO.update(self._model, attributes=self._properties)\n\n    def validate(self) -> None:\n        exceptions: list[ValidationError] = []\n\n        # Validate/populate model exists\n        self._model = DatasetDAO.find_by_id(self._model_id)\n        if not self._model:\n            raise DatasetNotFoundError()\n\n        # Check permission to update the dataset\n        try:\n            security_manager.raise_for_editorship(self._model)\n        except SupersetSecurityException as ex:\n            raise DatasetForbiddenError() from ex\n\n        # Validate/Populate editors\n        compute_subjects(self._model, self._properties, exceptions)\n\n        self._validate_dataset_source(exceptions)\n        self._validate_semantics(exceptions)\n\n        if exceptions:\n            raise DatasetInvalidError(exceptions=exceptions)\n\n    def _validate_dataset_source(self, exceptions: list[ValidationError]) -> None:\n        # we know we have a valid model\n        self._model = cast(SqlaTable, self._model)\n        database_id = self._properties.pop(\"database_id\", None)\n        new_db_connection = self._get_new_database_connection(database_id, exceptions)\n        db = new_db_connection or self._model.database\n        database_changed = new_db_connection is not None\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/dataset/update.py#L93-L129","documentation":"DatasetForbiddenError is raised by UpdateDatasetCommand.validate() when security_manager.raise_for_editorship(self._model) throws a SupersetSecurityException. Updating a dataset requires the user to be an owner or have write permission on datasets; read access is not enough.","triggerScenarios":"PUT/PATCH /api/v1/dataset/{id} (or saving the dataset editor UI) as a user who is not in owners and whose role lacks the dataset write capability.","commonSituations":"Gamma-derived roles that can explore charts on a dataset but were never granted edit. Ownership reassigned during offboarding; the departed user's scripts still hold a token. Embedded/guest tokens used against an endpoint they cannot access.","solutions":["Add the acting user to owners via an admin: PUT /api/v1/dataset/{id} with the merged owners list.","Grant the role 'can edit on Dataset' / appropriate write permission in the RBAC editor.","Run the update as an Admin.","Audit ownership in bulk: GET /api/v1/dataset?q=(table_name:eq:...) and inspect owners."],"exampleFix":"# before\nclient.put(\"/api/v1/dataset/42\", json={\"description\": \"x\"}, auth=viewer)\n# 403 Changing this dataset is forbidden\n\n# after\nclient.put(\"/api/v1/dataset/42\", json={\"description\": \"x\"}, auth=admin)","handlingStrategy":"validation","validationCode":"from superset import security_manager\n\nmodel = DatasetDAO.find_by_id(model_id)\nassert model is not None\ntry:\n    security_manager.raise_for_editorship(model)\nexcept SupersetSecurityException:\n    request_ownership(model)  # ask an admin to add you to owners","typeGuard":null,"tryCatchPattern":"try:\n    UpdateDatasetCommand(user, model_id, properties).run()\nexcept DatasetForbiddenError:\n    notify_admin_for_ownership(model_id)","preventionTips":["Run config-sync jobs with an owner/admin service account.","Keep owners lists current during offboarding handoffs.","Never silently retry 403s; fix the grant first."],"tags":["permissions","rbac","dataset","crud"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}