{"record":{"id":"1aa6fc17f92526d3","repo":"n8n-io/n8n","slug":"admin-cannot-change-role-on-global-owner","errorCode":null,"errorMessage":"Admin cannot change role on global owner","messagePattern":"Admin cannot change role on global owner","errorType":"exception","errorClass":"ForbiddenError","httpStatus":403,"severity":"error","filePath":"packages/cli/src/controllers/users.controller.ts","lineNumber":372,"sourceCode":"\t\t\tUsersController.ERROR_MESSAGES.CHANGE_ROLE;\n\n\t\tif (req.user.id === id) {\n\t\t\tthrow new ForbiddenError(CANNOT_CHANGE_OWN_ROLE);\n\t\t}\n\n\t\tconst targetUser = await this.userRepository.findOne({\n\t\t\twhere: { id },\n\t\t\trelations: ['role'],\n\t\t});\n\t\tif (targetUser === null) {\n\t\t\tthrow new NotFoundError(NO_USER);\n\t\t}\n\n\t\tif (\n\t\t\treq.user.role.slug === GLOBAL_ADMIN_ROLE.slug &&\n\t\t\ttargetUser.role.slug === GLOBAL_OWNER_ROLE.slug\n\t\t) {\n\t\t\tthrow new ForbiddenError(NO_ADMIN_ON_OWNER);\n\t\t}\n\n\t\tif (\n\t\t\treq.user.role.slug === GLOBAL_OWNER_ROLE.slug &&\n\t\t\ttargetUser.role.slug === GLOBAL_OWNER_ROLE.slug\n\t\t) {\n\t\t\tthrow new ForbiddenError(NO_OWNER_ON_OWNER);\n\t\t}\n\n\t\tawait this.userService.changeUserRole(targetUser, payload);\n\n\t\tthis.eventService.emit('user-changed-role', {\n\t\t\tuserId: req.user.id,\n\t\t\ttargetUserId: targetUser.id,\n\t\t\ttargetUserNewRole: payload.newRoleName,\n\t\t\tpublicApi: false,\n\t\t});\n","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/users.controller.ts#L354-L390","documentation":"Returned by PATCH /users/:id/role when the requester's role.slug is GLOBAL_ADMIN_ROLE.slug AND the target's role.slug is GLOBAL_OWNER_ROLE.slug. Admins are not permitted to act on the global owner's role. Message is the NO_ADMIN_ON_OWNER constant. HTTP 403.","triggerScenarios":"A global admin calls PATCH /users/<owner-id>/role; both role-slug comparisons match.","commonSituations":"Admin console where the owner is listed alongside admins; scripted role sync that includes the owner id; misconfiguration granting admin rights to a service account that then targets the owner.","solutions":["Only the current global owner (or the provisioning system) may reassign the owner role; use that path.","Filter the owner out of any admin-driven role-batch operation.","Surface a UI hint that the owner role cannot be changed by admins."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function canChangeRole(requesterSlug: string, targetSlug: string) {\n  return !(requesterSlug === 'global:admin' && targetSlug === 'global:owner');\n}\nif (!canChangeRole(reqUser.role.slug, target.role.slug)) {\n  throw new Error('Admins cannot change the owner role');\n}","typeGuard":"const isAdmin = (s: string) => s === 'global:admin';\nconst isOwner = (s: string) => s === 'global:owner';","tryCatchPattern":"try { await fetch(`/rest/users/${id}/role`, { method: 'PATCH', body }); }\ncatch (e) { if (e.statusCode === 403 && /change role on global owner/.test(e.message)) { /* route to owner */ } else throw e; }","preventionTips":["Filter global:owner out of admin role-change targets.","Use the ownership-transfer flow to reassign the owner role.","Surface role badges so admins can see owner rows distinctly."],"tags":["users","rbac","role-change","forbidden","owner","admin","authorization"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}