langflow-ai/langflow · error · HTTPException
Role still has active assignments — revoke them before delet
Error message
Role still has active assignments — revoke them before deleting
What it means
Raised by DELETE /api/v1/authz/roles/{role_id} when a row exists in authz_role_assignment referencing the role (the endpoint probes with a LIMIT 1 query before deleting). The DB would reject the delete via foreign key, so the API returns a proactive 409 telling you to revoke the assignments first.
Source
Thrown at src/backend/base/langflow/api/v1/authz_roles.py:281
System roles cannot be deleted; roles with active assignments return 409
(delete the assignments first).
"""
_require_superuser(current_user)
role = await session.get(AuthzRole, role_id)
if role is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Role not found")
if role.is_system:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="System roles cannot be deleted",
)
assigned = (
await session.exec(select(AuthzRoleAssignment).where(AuthzRoleAssignment.role_id == role_id).limit(1))
).first()
if assigned is not None:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Role still has active assignments — revoke them before deleting",
)
role_name = role.name
await session.delete(role)
await session.commit()
await safe_invalidate_role(get_authorization_service(), role_id, op="role:delete")
await audit_decision(
user_id=current_user.id,
action="role:delete",
obj=f"role:{role_id}",
result="allow",
details={"role_name": role_name},
)
logger.info("Deleted role id=%s", role_id)
View on GitHub (pinned to 976ec789d2)
Solutions
- List and revoke the role's assignments first (query the assignments endpoint and DELETE each one for this role_id), then retry the role delete
- Reassign affected users to a replacement role before removing the old one
- In teardown scripts, delete assignments before roles
Example fix
// before
await deleteRole(roleId); // 409: assignments exist
// after
const assignments = await listAssignments({ role_id: roleId });
for (const a of assignments) await deleteAssignment(a.id);
await deleteRole(roleId); Defensive patterns
Strategy: validation
Validate before calling
async function deleteRoleSafely(roleId: string) {
const assignments = await listAssignments({ role_id: roleId });
if (assignments.length > 0) {
throw new Error(`role still has ${assignments.length} assignment(s) — revoke first`);
}
return deleteRole(roleId);
} Try / catch
try {
await deleteRole(roleId);
} catch (e) {
if (e.status === 409 && /assignments/.test(e.detail)) {
await revokeAssignmentsFor(roleId);
await deleteRole(roleId);
} else throw e;
} Prevention
- In teardown scripts, always delete role assignments before roles
- Surface 'N active assignments' in the UI before allowing a delete attempt
When it happens
Trigger: DELETE /authz/roles/{id} while any user or team still has that role assigned via POST /authz/assignments (authz_role_assignment rows with role_id = id).
Common situations: Decommissioning a role that is still granted to a team; test fixtures that assign roles and forget to revoke them; ordering bug in teardown scripts that deletes roles before assignments.
Related errors
- Name conflict — another role already uses this name
- System roles cannot be deleted
- name cannot be null
- permissions cannot be null; pass an empty list to clear
- You don't have permission to delete this flow.
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/6c2d84b1394e8eef.
Report an issue: GitHub.