langflow-ai/langflow · warning · HTTPException
Role with name {payload.name!r} already exists
Error message
Role with name {payload.name!r} already exists What it means
Raised by POST /api/v1/authz/roles when commit hits an IntegrityError on the unique role name — a role with the same name already exists. The route rolls back and returns HTTP 409 with the conflicting name embedded in the detail.
Source
Thrown at src/backend/base/langflow/api/v1/authz_roles.py:136
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="parent_role_id does not reference an existing role",
)
role = AuthzRole(
name=payload.name,
description=payload.description,
is_system=False,
permissions=list(payload.permissions),
parent_role_id=payload.parent_role_id,
created_by=current_user.id,
)
session.add(role)
try:
await session.commit()
except IntegrityError as exc:
await session.rollback()
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail=f"Role with name {payload.name!r} already exists",
) from exc
await session.refresh(role)
await safe_invalidate_all(get_authorization_service(), op="role:create")
await audit_decision(
user_id=current_user.id,
action="role:create",
obj=f"role:{role.id}",
result="allow",
details={
"role_name": role.name,
"permissions": list(role.permissions),
"parent_role_id": str(role.parent_role_id) if role.parent_role_id else None,
},
)
logger.info("Created role %s (id=%s)", role.name, role.id)
return RoleRead.model_validate(role)View on GitHub (pinned to 976ec789d2)
Solutions
- On 409, GET /api/v1/authz/roles and reuse the existing role instead of creating it
- Use upsert-style logic in scripts: check by name, create only if missing
- Pick a different, namespaced name (e.g. 'team-dev') for custom roles
Example fix
// before
await api.post('/authz/roles', { name: 'developer' });
// after
const roles = await api.get('/authz/roles');
let role = roles.find(r => r.name === 'developer');
if (!role) role = (await api.post('/authz/roles', { name: 'developer' })).data; Defensive patterns
Strategy: try-catch
Validate before calling
const roles = await api.get('/api/v1/authz/roles');
if (roles.some(r => r.name === name)) return roles.find(r => r.name === name)!; Try / catch
try { return await createRole(name, perms); }
catch (e) { if (e.status !== 409) throw e; return (await listRoles()).find(r => r.name === name)!; } Prevention
- Use find-or-create semantics in provisioning scripts
- Avoid reusing system role names (viewer/developer/admin)
- Namespace custom role names per team to avoid collisions
When it happens
Trigger: POST {"name": "developer"} when a custom (or system) role named 'developer' already exists; system roles viewer/developer/admin are seeded by the authz foundations migration, so re-creating those names always conflicts.
Common situations: Re-running provisioning scripts that assume create-if-missing semantics, or attempting to recreate a system role as a custom role. The 409 detail includes the name via {payload.name!r} to make the conflict obvious.
Related errors
- Assignment already exists for this user/role/domain
- Superuser required to administer roles.
- Role not found
- parent_role_id does not reference an existing role
- System roles cannot be modified
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/dba7d1697349d0cb.
Report an issue: GitHub.