apache/superset · error · TagNotFoundValidationError
Tag ID {tag_id} not found
Error message
Tag ID {tag_id} not found What it means
Inside validate_tags, after the permission check passes, each newly added tag ID is checked with TagDAO.find_by_id; an unknown ID raises TagNotFoundValidationError with the offending ID. This guards against associating nonexistent custom tags with dashboards/charts/datasets.
Source
Thrown at superset/commands/utils.py:248
if Counter(current_custom_tags) == Counter(new_tag_ids):
return
# No perm to tags assets
if not (
security_manager.can_access("can_write", "Tag")
or security_manager.can_access("can_tag", object_type.name.capitalize())
):
validation_error = (
f"You do not have permission to manage tags on {object_type.name}s"
)
raise TagForbiddenError(validation_error)
# Validate if new tags already exist
additional_tags = [tag for tag in new_tag_ids if tag not in current_custom_tags]
for tag_id in additional_tags:
if not TagDAO.find_by_id(tag_id):
validation_error = f"Tag ID {tag_id} not found"
raise TagNotFoundValidationError(validation_error)
return
def update_tags(
object_type: ObjectType,
object_id: int,
current_tags: list[Tag],
new_tag_ids: list[int],
) -> None:
"""
Helper function for update commands, to update the tag relationship.
:param object_id: The object (dashboard, chart, etc) ID
:param object_type: The object type
:param current_tags: list of current tags
:param new_tag_ids: list of tags specified in the update payload
"""View on GitHub (pinned to f4587218dd)
Solutions
- Fetch the current tag list (GET /api/v1/tag) and map names to live IDs before submitting.
- Create missing tags first (if the user has can_write on Tag), then reference their IDs.
- Remove nonexistent tag IDs from the payload.
Example fix
# before
{"tags": [5, 999]} # 999 does not exist
# after
valid = {t.id for t in TagDAO.find_all()} # or GET /api/v1/tag
{"tags": [t for t in [5, 999] if t in valid]} Defensive patterns
Strategy: validation
Validate before calling
from superset.daos.tag import TagDAO
bad = [tid for tid in new_tag_ids if TagDAO.find_by_id(tid) is None]
if bad:
raise ValueError(f"unknown tag ids: {bad}") Try / catch
try:
update_tags(object_type, object_id, current_tags, new_tag_ids)
except TagNotFoundValidationError as e:
drop_ids_from_message_and_retry(e) Prevention
- Map tag names to fresh IDs at request time
- Create tags before referencing them
When it happens
Trigger: PATCHing an object with a tags array containing an ID that is not an existing custom tag — stale tag list from another environment, deleted tag, or hand-crafted ID.
Common situations: Importing dashboards with tag references without importing tags; tag deleted by an admin while a user had the tag picker open; scripts copying tag IDs across instances.
Related errors
- Theme not found.
- Theme not found.
- Datasource does not exist
- Chart with ID {annotation_layer["value"]} (referenced by ann
- Dashboard %(dashboard_id)s not found
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/0764b732bafd162e.
Report an issue: GitHub.