apache/superset · error · TagForbiddenError

You do not have permission to manage tags on {object_type.na

Error message

You do not have permission to manage tags on {object_type.name}s

What it means

validate_tags raises TagForbiddenError when the caller tries to change custom tags on an object but lacks both 'can_write' on the Tag resource and 'can_tag' on the specific object type. Superset splits tag authority: full Tag writers can manage all tag associations; per-object-type 'can_tag' holders may only associate existing tags.

Source

Thrown at superset/commands/utils.py:241

    # `tags` not part of the update payload
    if new_tag_ids is None:
        return

    # No changes in the list
    current_custom_tags = [tag.id for tag in current_tags if tag.type == TagType.custom]
    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:
    """

View on GitHub (pinned to f4587218dd)

Solutions

  1. Grant the role can_tag on the object type (e.g. 'can_tag on Dashboard') or can_write on Tag.
  2. If the user should not tag at all, remove tag editing from their UI flow so the request is never sent.
  3. Audit role permissions with the /api/v1/permissions or role API to confirm the exact missing permission.

Example fix

# before
curl -X PATCH .../api/v1/dashboard/1 -d '{"tags":[3]}'  # 403 TagForbiddenError

# after (admin grants permission first)
flask fab add-permissions -r TagEditor -p can_write -r Tag  # or add can_tag on Dashboard
Defensive patterns

Strategy: validation

Validate before calling

from superset import security_manager
ok = security_manager.can_access("can_write", "Tag") or security_manager.can_access(
    "can_tag", object_type.capitalize()
)
if not ok:
    raise PermissionError("tag management not permitted")

Try / catch

from superset.commands.tag.exceptions import TagForbiddenError
try:
    update_tags(...)
except TagForbiddenError:
    skip_tag_update_keep_object_save()

Prevention

When it happens

Trigger: PUT/PATCH on a dashboard/chart/dataset with a changed 'tags' list while the user's role has neither can_write on Tag nor can_tag on Dashboard/Chart/etc. Also triggered by tag assignment endpoints when permissions were trimmed.

Common situations: Custom roles built without copying the can_tag permissions; recent role refactors dropping Tag permissions; Gamma-style users attempting to tag after an upgrade that introduced the can_tag model.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/9357d6c180b9388b. Report an issue: GitHub.