{"record":{"id":"0658decf40fa48cc","repo":"apache/superset","slug":"tag-not-found-0658de","errorCode":null,"errorMessage":"Tag not found.","messagePattern":"Tag not found\\.","errorType":"exception","errorClass":"TagNotFoundError","httpStatus":404,"severity":"warning","filePath":"superset/daos/tag.py","lineNumber":277,"sourceCode":"        return TagDAO.get_tagged_objects_by_tag_ids(tag_ids, obj_types)\n\n    @staticmethod\n    def favorite_tag_by_id_for_current_user(  # pylint: disable=invalid-name\n        tag_id: int,\n    ) -> None:\n        \"\"\"\n        Marks a specific tag as a favorite for the current user.\n\n        :param tag_id: The id of the tag that is to be marked as favorite\n        \"\"\"\n\n        tag = TagDAO.find_by_id(tag_id)\n        user = g.user\n\n        if not user:\n            raise MissingUserContextException(message=\"User doesn't exist\")\n        if not tag:\n            raise TagNotFoundError()\n\n        tag.users_favorited.append(user)\n\n    @staticmethod\n    def remove_user_favorite_tag(tag_id: int) -> None:\n        \"\"\"\n        Removes a tag from the current user's favorite tags.\n\n        :param tag_id: The id of the tag that is to be removed from the favorite tags\n        \"\"\"\n        tag = TagDAO.find_by_id(tag_id)\n        user = g.user\n\n        if not user:\n            raise MissingUserContextException(message=\"User doesn't exist\")\n        if not tag:\n            raise TagNotFoundError()\n","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/daos/tag.py#L259-L295","documentation":"Raised by TagDAO.add_user_favorite_tag when TagDAO.find_by_id(tag_id) returns nothing — the favorite feature cannot favorite a nonexistent tag. It is the TagNotFoundError from superset.tags/commands (a CommandException), distinct from the tag.py DAO-level NoResultFound messages used for name lookups. The check order is user first, then tag, so a valid user plus a bad id lands here.","triggerScenarios":"POST favorite-tag with an id of a deleted tag; integer id of a tag from another environment after metadata restore; typos in hand-crafted API payloads; race where the tag is deleted between the client listing tags and favoriting.","commonSituations":"Stale tag lists in the UI after another user deletes tags; scripts replaying recorded ids; environments rebuilt from dumps where tag ids shifted.","solutions":["Re-fetch the tag list and use a current tag_id.","Catch TagNotFoundError and refresh/skip gracefully in the UI.","Prefer resolving tags by name in scripts, then favorite by the freshly looked-up id.","Ensure the delete-tag flow also clears client-side favorite state."],"exampleFix":"# before\nTagDAO.add_user_favorite_tag(1234)  # deleted tag -> TagNotFoundError\n\n# after\ntag = TagDAO.find_by_id(tag_id)\nif tag:\n    TagDAO.add_user_favorite_tag(tag_id)\nelse:\n    refresh_tag_list()  # resync ids before favoriting","handlingStrategy":"validation","validationCode":"from superset.daos.tag import TagDAO\n\ndef tag_id_exists(tag_id: int) -> bool:\n    return TagDAO.find_by_id(tag_id) is not None","typeGuard":null,"tryCatchPattern":"from superset.tags.exceptions import TagNotFoundError\ntry:\n    TagDAO.add_user_favorite_tag(tag_id)\nexcept TagNotFoundError:\n    refresh_tag_list()  # ids are stale; re-resolve and let the user retry","preventionTips":["Resolve tag ids from a fresh tag list before favoriting.","In scripts, look tags up by name and favorite by the returned id.","Handle not-found as a signal to refresh, not to retry blindly."],"tags":["tags","favorites","not-found","dao"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}