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

  1. 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
  2. Reassign affected users to a replacement role before removing the old one
  3. 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

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


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/6c2d84b1394e8eef. Report an issue: GitHub.