{"record":{"id":"904395c51c57373c","repo":"passbolt/passbolt_api","slug":"you-do-not-have-the-permission-to-edit-shared-tags-on-this","errorCode":null,"errorMessage":"You do not have the permission to edit shared tags on this resource.","messagePattern":"You do not have the permission to edit shared tags on this resource\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Tags/src/Service/Tags/ResourcesTagsAddService.php","lineNumber":129,"sourceCode":"        $isOwner = $resource->permission->type === Permission::OWNER;\n\n        [$clearTextTags, $encryptedTags] = $this->extractClearTextAndEncryptedTags($data);\n\n        // Do not link tag again if already linked with the resource\n        foreach ($resource->get('tags') as $i => $tag) {\n            // Do not patch tags owned by other users.\n            if (!is_null($tag->_joinData->user_id) && $tag->_joinData->user_id != $userId) {\n                continue;\n            }\n\n            if (!is_null($tag->slug)) {\n                // V4\n                $tagFoundIndex = array_search($tag->slug, $clearTextTags);\n                if ($tagFoundIndex === false) {\n                    // If the user is not owner of the resource they cannot unlink shared tags\n                    if ($tag->is_shared && !$isOwner) {\n                        $msg = __('You do not have the permission to edit shared tags on this resource.');\n                        throw new BadRequestException($msg);\n                    }\n                    unset($resource['tags'][$i]);\n                } else {\n                    unset($clearTextTags[$tagFoundIndex]);\n                }\n            } else {\n                // V5\n                if ($tag->is_shared && !$isOwner) {\n                    $msg = __('You do not have the permission to edit shared tags on this resource.');\n                    throw new BadRequestException($msg);\n                }\n                unset($resource['tags'][$i]);\n            }\n        }\n\n        // If the user is not owner of the resource he cannot edit shared tags\n        if (!$isOwner) {\n            if (!empty(preg_grep('/(^#|,#)/', $clearTextTags))) {","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Tags/src/Service/Tags/ResourcesTagsAddService.php#L111-L147","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Keep the shared tags (prefixed with '#') in the submitted tags payload, or","Request resource ownership to be allowed to edit shared tags.","Have the resource owner perform the shared-tag edit.","Update client code to preserve existing tags it does not intend to change."],"exampleFix":"// before\n{\"tags\": [\"personal-tag\"]}            // drops shared #tag -> 400\n// after\n{\"tags\": [\"personal-tag\", \"#shared-tag\"]}","handlingStrategy":"validation","validationCode":"// before PATCH, ensure shared tags are preserved by non-owners\nconst shared = currentTags.filter(t => t.startsWith('#'));\nif (!isOwner && !shared.every(s => newTags.includes(s))) throw new Error('cannot unlink shared tag');","typeGuard":null,"tryCatchPattern":"try { patchTags(payload) } catch (BadRequestException $e) { if (msg.includes('shared tags')) readdSharedTags(); }","preventionTips":["Always submit the full existing tag list","Treat '#' prefix as protected for non-owners","Check ownership before editing tags","Update client UIs to not silently drop shared tags"],"tags":["permissions","shared-tags","bad-request","v4-tags"],"backgroundTag":"permission-denied","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}