langflow-ai/langflow · error · HTTPException
Superuser required to administer roles.
Error message
Superuser required to administer roles.
What it means
Superuser gate on the role-administration routes under /api/v1/authz/roles (create/update/delete; list and read are open to any authenticated user). A non-superuser calling a mutating role route gets HTTP 403 'Superuser required to administer roles.'
Source
Thrown at src/backend/base/langflow/api/v1/authz_roles.py:37
safe_invalidate_role,
)
from langflow.services.authorization.utils import audit_decision
from langflow.services.database.models.auth import AuthzRole, AuthzRoleAssignment
from langflow.services.deps import get_authorization_service
router = APIRouter(prefix="/authz/roles", tags=["Authorization"])
# Match ``authz_shares``: cap any single list call so an authenticated client
# (or a buggy frontend) can't enumerate the entire role/team catalog in one
# request. 100 default / 200 max is enough for typical UI dropdowns.
_LIST_MAX_LIMIT = 200
_LIST_DEFAULT_LIMIT = 100
def _require_superuser(user) -> None:
"""Superuser-only gate. Role admin is an operations action."""
if not getattr(user, "is_superuser", False):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Superuser required to administer roles.",
)
async def _detect_parent_cycle(
session: DbSession,
*,
role_id: UUID,
proposed_parent_id: UUID,
) -> bool:
"""Walk the parent chain from ``proposed_parent_id``; True if ``role_id`` appears.
Used to reject ``PATCH`` requests that would set a role as its own ancestor.
Walks at most ``len(all_roles)`` steps so a pre-existing cycle terminates.
"""
visited: set[UUID] = set()
cursor: UUID | None = proposed_parent_idView on GitHub (pinned to 976ec789d2)
Solutions
- Use the seed superuser credentials (LANGFLOW_SUPERUSER env vars) to obtain the token for role admin
- Restrict the role-management UI to superusers so the 403 never fires in production
- Verify is_superuser on the /api/v1/users/whoami response before showing admin controls
Defensive patterns
Strategy: validation
Validate before calling
const me = await api.get('/users/whoami');
if (!me.is_superuser) disableRoleAdminUI(); Type guard
const canAdminRoles = (u: { is_superuser?: boolean } | null): boolean =>
Boolean(u?.is_superuser); Try / catch
catch (e) { if (e.status === 403) notify('Superuser required'); return; } Prevention
- Read and write are different gates — reads are open, mutations are superuser-only; plan tokens accordingly
- Use the seed superuser for provisioning scripts
- Hide create/update/delete role controls for non-superusers
When it happens
Trigger: POST/PATCH/DELETE /api/v1/authz/roles* with a token whose user has is_superuser=False. Listing (GET '') and reading a single role (GET /{role_id}) do not hit this, only the mutations do.
Common situations: Frontends that show the role-admin UI to all logged-in users, scripts authenticated as a normal workspace user, or forgetting to switch tokens when moving from read-only inspection to role editing.
Related errors
- Superuser required to administer role assignments.
- Role not found
- parent_role_id does not reference an existing role
- Role with name {payload.name!r} already exists
- System roles cannot be modified
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/245342e9b57915d4.
Report an issue: GitHub.