{"record":{"id":"6f8c93fd940c4371","repo":"apache/superset","slug":"theme-not-found-6f8c93","errorCode":null,"errorMessage":"Theme not found.","messagePattern":"Theme not found\\.","errorType":"exception","errorClass":"ThemeNotFoundError","httpStatus":500,"severity":"error","filePath":"superset/commands/theme/update.py","lineNumber":50,"sourceCode":"\nclass UpdateThemeCommand(UpdateMixin):\n    def __init__(self, model_id: int, data: dict[str, Any]):\n        self._model_id = model_id\n        self._properties = data.copy()\n        self._model: Optional[Theme] = None\n\n    @transaction(on_error=partial(on_error, reraise=Exception))\n    def run(self) -> Theme:\n        self.validate()\n        assert self._model\n        theme = ThemeDAO.update(self._model, self._properties)\n        return theme\n\n    def validate(self) -> None:\n        # Validate theme exists\n        self._model = ThemeDAO.find_by_id(self._model_id)\n        if not self._model:\n            raise ThemeNotFoundError()\n\n        # Check if it's a system theme\n        if self._model.is_system:\n            raise SystemThemeProtectedError()\n","sourceCodeStart":32,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/commands/theme/update.py#L32-L55","documentation":"Raised by UpdateThemeCommand.validate() when the theme to update cannot be found by ID. The update command resolves the model first; a missing row raises ThemeNotFoundError before any property merge happens, so no partial update can occur.","triggerScenarios":"PUT/PATCH on /api/v1/theme/<id> with an ID that was deleted; two editors where one deleted the theme the other is still editing; passing a wrong type of ID (e.g. UUID string where an integer PK is expected).","commonSituations":"Editing a theme in a long-open browser tab after the theme was removed elsewhere; API integrations holding cached IDs; DB rows cleared between environments.","solutions":["Re-fetch the theme list and confirm the target ID still exists before PATCHing.","Handle 404 in the client by reloading the theme collection and discarding stale edits.","If IDs are unstable in your setup, migrate theme references to stable identifiers."],"exampleFix":"# before\nUpdateThemeCommand(model_id=42, properties={...}).run()\n\n# after\nif ThemeDAO.find_by_id(42) is None:\n    raise LookupError(\"theme 42 deleted; reload themes\")\nUpdateThemeCommand(model_id=42, properties={...}).run()","handlingStrategy":"validation","validationCode":"if ThemeDAO.find_by_id(model_id) is None:\n    raise LookupError(\"theme deleted; reload\")","typeGuard":null,"tryCatchPattern":"try:\n    UpdateThemeCommand(model_id, properties).run()\nexcept ThemeNotFoundError:\n    discard_stale_edits_and_reload()","preventionTips":["Treat 404 on theme update as a signal to reload state, not retry blindly","Confirm ID type matches integer PK"],"tags":["theme","not-found","validation","backend"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}