{"record":{"id":"dba7d1697349d0cb","repo":"langflow-ai/langflow","slug":"role-with-name-payload-name-r-already-exists","errorCode":null,"errorMessage":"Role with name {payload.name!r} already exists","messagePattern":"Role with name (.+?) already exists","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"warning","filePath":"src/backend/base/langflow/api/v1/authz_roles.py","lineNumber":136,"sourceCode":"            raise HTTPException(\n                status_code=status.HTTP_400_BAD_REQUEST,\n                detail=\"parent_role_id does not reference an existing role\",\n            )\n\n    role = AuthzRole(\n        name=payload.name,\n        description=payload.description,\n        is_system=False,\n        permissions=list(payload.permissions),\n        parent_role_id=payload.parent_role_id,\n        created_by=current_user.id,\n    )\n    session.add(role)\n    try:\n        await session.commit()\n    except IntegrityError as exc:\n        await session.rollback()\n        raise HTTPException(\n            status_code=status.HTTP_409_CONFLICT,\n            detail=f\"Role with name {payload.name!r} already exists\",\n        ) from exc\n    await session.refresh(role)\n    await safe_invalidate_all(get_authorization_service(), op=\"role:create\")\n    await audit_decision(\n        user_id=current_user.id,\n        action=\"role:create\",\n        obj=f\"role:{role.id}\",\n        result=\"allow\",\n        details={\n            \"role_name\": role.name,\n            \"permissions\": list(role.permissions),\n            \"parent_role_id\": str(role.parent_role_id) if role.parent_role_id else None,\n        },\n    )\n    logger.info(\"Created role %s (id=%s)\", role.name, role.id)\n    return RoleRead.model_validate(role)","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_roles.py#L118-L154","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait api.post('/authz/roles', { name: 'developer' });\n\n// after\nconst roles = await api.get('/authz/roles');\nlet role = roles.find(r => r.name === 'developer');\nif (!role) role = (await api.post('/authz/roles', { name: 'developer' })).data;","handlingStrategy":"try-catch","validationCode":"const roles = await api.get('/api/v1/authz/roles');\nif (roles.some(r => r.name === name)) return roles.find(r => r.name === name)!;","typeGuard":null,"tryCatchPattern":"try { return await createRole(name, perms); }\ncatch (e) { if (e.status !== 409) throw e; return (await listRoles()).find(r => r.name === name)!; }","preventionTips":["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"],"tags":["authz","rbac","http-409","roles","unique-constraint"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}