passbolt/passbolt_api · error · BadRequestException

You do not have the permission to edit shared tags on this…

Error message

You do not have the permission to edit shared tags on this resource.

What it means

In patchTagsEntities (V4 tag branch), when a user who is not an owner of the resource submits a tags payload that no longer includes an existing shared tag, the service refuses to unlink it and throws a BadRequestException. Only resource owners may add or remove shared (is_shared) tags.

Solutions

  1. Keep the shared tags (prefixed with '#') in the submitted tags payload, or
  2. Request resource ownership to be allowed to edit shared tags.
  3. Have the resource owner perform the shared-tag edit.
  4. Update client code to preserve existing tags it does not intend to change.

Example fix

// before
{"tags": ["personal-tag"]}            // drops shared #tag -> 400
// after
{"tags": ["personal-tag", "#shared-tag"]}
Defensive patterns

Strategy: validation

Validate before calling

// before PATCH, ensure shared tags are preserved by non-owners
const shared = currentTags.filter(t => t.startsWith('#'));
if (!isOwner && !shared.every(s => newTags.includes(s))) throw new Error('cannot unlink shared tag');

Try / catch

try { patchTags(payload) } catch (BadRequestException $e) { if (msg.includes('shared tags')) readdSharedTags(); }

Prevention

When it happens

Trigger: PATCH on a resource's tags by a non-owner whose submitted tag list omits a currently attached shared tag (the tag would be unlinked).

Common situations: Client UIs loading and re-submitting a truncated tag list; collaborators editing tags without realizing a '#shared' tag is attached; API scripts filtering out tags they cannot read.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/904395c51c57373c. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Tags/src/Service/Tags/ResourcesTagsAddService.php:129

        $isOwner = $resource->permission->type === Permission::OWNER;

        [$clearTextTags, $encryptedTags] = $this->extractClearTextAndEncryptedTags($data);

        // Do not link tag again if already linked with the resource
        foreach ($resource->get('tags') as $i => $tag) {
            // Do not patch tags owned by other users.
            if (!is_null($tag->_joinData->user_id) && $tag->_joinData->user_id != $userId) {
                continue;
            }

            if (!is_null($tag->slug)) {
                // V4
                $tagFoundIndex = array_search($tag->slug, $clearTextTags);
                if ($tagFoundIndex === false) {
                    // If the user is not owner of the resource they cannot unlink shared tags
                    if ($tag->is_shared && !$isOwner) {
                        $msg = __('You do not have the permission to edit shared tags on this resource.');
                        throw new BadRequestException($msg);
                    }
                    unset($resource['tags'][$i]);
                } else {
                    unset($clearTextTags[$tagFoundIndex]);
                }
            } else {
                // V5
                if ($tag->is_shared && !$isOwner) {
                    $msg = __('You do not have the permission to edit shared tags on this resource.');
                    throw new BadRequestException($msg);
                }
                unset($resource['tags'][$i]);
            }
        }

        // If the user is not owner of the resource he cannot edit shared tags
        if (!$isOwner) {
            if (!empty(preg_grep('/(^#|,#)/', $clearTextTags))) {

View on GitHub (pinned to 31c1bbc10f)