{"record":{"id":"dcc134ec2aefb6c1","repo":"n8n-io/n8n","slug":"your-instance-is-not-licensed-to-use-role-role","errorCode":null,"errorMessage":"Your instance is not licensed to use role \"${role}\".","messagePattern":"Your instance is not licensed to use role \"(.+?)\"\\.","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/cli/src/controllers/project.controller.ts","lineNumber":327,"sourceCode":"\t\t\tconst relations = await this.projectsService.getProjectRelations(projectId);\n\t\t\tthis.eventService.emit('team-project-updated', {\n\t\t\t\tuserId: req.user.id,\n\t\t\t\trole: req.user.role.slug,\n\t\t\t\tmembers: relations.map((r) => ({ userId: r.userId, role: r.role.slug })),\n\t\t\t\tprojectId,\n\t\t\t});\n\n\t\t\t// Response semantics:\n\t\t\t// - If at least one user was added, return 201. When there are also conflicts, include them in the body.\n\t\t\t// - If no users were added but conflicts exist, return 409 with conflicts.\n\t\t\tif (added.length > 0) {\n\t\t\t\treturn conflicts.length > 0 ? res.status(201).json({ conflicts }) : res.status(201).send();\n\t\t\t}\n\t\t\tif (conflicts.length > 0) return res.status(409).json({ conflicts });\n\t\t\treturn res.status(200).send();\n\t\t} catch (e) {\n\t\t\tif (e instanceof UnlicensedProjectRoleError) {\n\t\t\t\tthrow new BadRequestError(e.message);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t@Patch('/:projectId/users/:userId')\n\t@ProjectScope('project:update')\n\tasync changeProjectUserRole(\n\t\treq: AuthenticatedRequest,\n\t\tres: Response,\n\t\t@Param('projectId') projectId: string,\n\t\t@Param('userId') userId: string,\n\t\t@Body body: ChangeUserRoleInProject,\n\t) {\n\t\tawait this.assertProjectRolesNotManaged();\n\n\t\ttry {\n\t\t\tawait this.projectsService.changeUserRoleInProject(projectId, userId, body.role);","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/project.controller.ts#L309-L345","documentation":"Adding users to a project can assign each a project role; if a requested role is not covered by the current license, projectsService throws UnlicensedProjectRoleError (constructed as 'Your instance is not licensed to use role \"<role>\".'), which the addProjectUsers catch converts to a 400 BadRequestError.","triggerScenarios":"POST /:projectId/users with a payload role that maps to an AssignableProjectRole not enabled by the active license (e.g. an enterprise-only project role on a lower tier).","commonSituations":"Assigning a gated project role (limited editor / custom role) on a Community or Pro plan that does not include it; license downgraded below the role set in use.","solutions":["Use a project role that the current license covers.","Upgrade the license tier to unlock the requested role.","Check the assignable roles for the license before issuing the add-users call."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the requested role against licensed assignable roles before POST.\nasync function isRoleLicensed(getAssignableRoles, role) {\n  const allowed = await getAssignableRoles();\n  return allowed.includes(role);\n}","typeGuard":"function isLicensedRole(role, allowedRoles) {\n  return Array.isArray(allowedRoles) && allowedRoles.includes(role);\n}","tryCatchPattern":"try {\n  await api.post(`/projects/${projectId}/users`, payload);\n} catch (e) {\n  if (e.status === 400 && /not licensed to use role/.test(e.message)) {\n    // choose a licensed role and retry\n  } else { throw e; }\n}","preventionTips":["Fetch and cache the licensed assignable roles for the UI role picker.","Guard against typos in role slugs before submitting."],"tags":["license","rbac","projects","memberships"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}