n8n-io/n8n · error · ForbiddenError
Project roles are managed automatically and cannot be change
Error message
Project roles are managed automatically and cannot be changed manually
What it means
When project roles are provisioned automatically by an external system (SSO/SCIM role mapping), n8n locks down all manual membership mutations. assertProjectRolesNotManaged() throws 403 ForbiddenError if provisioningService.isProjectRoleManaged() returns true.
Source
Thrown at packages/cli/src/controllers/project.controller.ts:282
_res: Response,
@Body payload: UpdateProjectDto,
@Param('projectId') projectId: string,
) {
await this.projectsService.updateProject(projectId, payload);
this.eventService.emit('team-project-updated', {
userId: req.user.id,
role: req.user.role.slug,
projectId,
...(payload.customTelemetryTags !== undefined
? { otelProjectCustomTagsCount: payload.customTelemetryTags.length }
: {}),
});
}
/** Throws when project roles are provisioned automatically, so manual membership changes are disallowed. */
private async assertProjectRolesNotManaged() {
if (await this.provisioningService.isProjectRoleManaged()) {
throw new ForbiddenError(
'Project roles are managed automatically and cannot be changed manually',
);
}
}
@Post('/:projectId/users')
@ProjectScope('project:update')
async addProjectUsers(
req: AuthenticatedRequest,
res: Response,
@Param('projectId') projectId: string,
@Body payload: AddUsersToProjectDto,
) {
await this.assertProjectRolesNotManaged();
try {
const { added, conflicts, project } =
await this.projectsService.addUsersWithConflictSemantics(projectId, payload.relations);
View on GitHub (pinned to 5ac6606e81)
Solutions
- Manage project membership through the SSO/SCIM provider's role/group mappings instead of the API.
- If manual control is genuinely required, disable managed-roles mode (and understand the implications) via the provisioning/SSO configuration.
Defensive patterns
Strategy: try-catch
Validate before calling
// If a metadata endpoint exposes managed-roles mode, check it before attempting mutations.
async function isManaged(getProvisioningState) {
return Boolean((await getProvisioningState())?.projectRoleManaged);
} Try / catch
try {
await api.post(`/projects/${projectId}/users`, payload);
} catch (e) {
if (e.status === 403 && /managed automatically/.test(e.message)) {
// instruct admin to use the SSO/SCIM provider for membership changes
} else { throw e; }
} Prevention
- When SSO/SCIM role mapping is on, drive memberships from the IdP.
- Surface managed-roles state in the UI to disable manual controls.
When it happens
Trigger: Any controller action guarded by assertProjectRolesNotManaged() — adding, changing, or deleting project users — invoked while provisioning reports that roles are externally managed.
Common situations: Enterprise SSO/SCIM with role mapping enabled; an admin attempts to add or reassign a project member through the UI or REST API while managed-roles mode is on.
Related errors
- Instance roles are managed automatically and cannot be chang
- Down migration only possible when there are no projects. Ple
- Could not find a personal project for this user
- Your instance is not licensed to use role "${role}".
- Role not found
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/5638e4d5d0502b74.
Report an issue: GitHub.