langflow-ai/langflow · warning · HTTPException
A role cannot be its own parent
Error message
A role cannot be its own parent
What it means
Raised by PATCH /api/v1/authz/roles/{role_id} when parent_role_id in the payload equals the role's own id. Self-parenting is rejected with HTTP 400 before any cycle walk, as the trivial cycle case.
Source
Thrown at src/backend/base/langflow/api/v1/authz_roles.py:186
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 modified",
)
# Use presence checks (model_fields_set) rather than ``is not None`` so PATCH
# can clear nullable fields. An explicit ``"description": null`` in the body
# marks the field as set and assigns None; omitting it leaves the row alone.
fields_set = payload.model_fields_set
if "parent_role_id" in fields_set:
if payload.parent_role_id is None:
role.parent_role_id = None
else:
if payload.parent_role_id == role.id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="A role cannot be its own parent",
)
parent = await session.get(AuthzRole, payload.parent_role_id)
if parent is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="parent_role_id does not reference an existing role",
)
if await _detect_parent_cycle(session, role_id=role.id, proposed_parent_id=payload.parent_role_id):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Setting this parent would create a role hierarchy cycle",
)
role.parent_role_id = payload.parent_role_id
if "description" in fields_set:
# description is nullable on the DB side — None is a legitimate clear.View on GitHub (pinned to 976ec789d2)
Solutions
- Exclude the role being edited from its own parent dropdown options
- In scripts, assert parentId !== roleId before PATCH
- If cloning a role, leave parent_role_id null or point it at the true parent, never the new/existing row id
Example fix
// before
await api.patch(`/authz/roles/${id}`, { parent_role_id: id });
// after
if (parentId === id) throw new Error('role cannot be its own parent');
await api.patch(`/authz/roles/${id}`, { parent_role_id: parentId }); Defensive patterns
Strategy: type-guard
Validate before calling
if (parentRoleId === roleId) throw new Error('role cannot be its own parent'); Type guard
const isValidParent = (parentId: string | null, selfId: string): boolean => parentId === null || parentId !== selfId;
Prevention
- Exclude the edited role from its own parent dropdown
- Assert parentId !== roleId in scripts before PATCH
- When cloning roles, leave parent_role_id null
When it happens
Trigger: PATCH {"parent_role_id": "<same-uuid-as-path>"} — typically a form bug where the parent dropdown's selected value defaults to the role being edited.
Common situations: Admin UI edit forms that pre-select the current role in the parent picker, or scripts that copy the role row and reuse its id for parent_role_id when cloning.
Related errors
- parent_role_id does not reference an existing role
- Setting this parent would create a role hierarchy cycle
- System roles cannot be modified
- `since` must be strictly less than `until`
- resource_ids capped at {_MAX_RESOURCE_IDS}
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/9163af9ee7102ae5.
Report an issue: GitHub.