langflow-ai/langflow · warning · HTTPException

parent_role_id does not reference an existing role

Error message

parent_role_id does not reference an existing role

What it means

Raised by POST /api/v1/authz/roles when the optional parent_role_id in RoleCreate does not reference an existing AuthzRole. The route validates the parent with session.get before inserting, returning HTTP 400 rather than surfacing a DB foreign-key error.

Source

Thrown at src/backend/base/langflow/api/v1/authz_roles.py:118

    if role is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Role not found")
    return RoleRead.model_validate(role)


@router.post("", response_model=RoleRead, status_code=status.HTTP_201_CREATED)
@router.post("/", response_model=RoleRead, status_code=status.HTTP_201_CREATED)
async def create_role(
    payload: RoleCreate,
    current_user: CurrentActiveUser,
    session: DbSession,
) -> RoleRead:
    """Create a custom (non-system) role. Superuser-only."""
    _require_superuser(current_user)

    if payload.parent_role_id is not None:
        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",
            )

    role = AuthzRole(
        name=payload.name,
        description=payload.description,
        is_system=False,
        permissions=list(payload.permissions),
        parent_role_id=payload.parent_role_id,
        created_by=current_user.id,
    )
    session.add(role)
    try:
        await session.commit()
    except IntegrityError as exc:
        await session.rollback()
        raise HTTPException(

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Create/import parent roles before children
  2. Resolve parent ids by name from GET /api/v1/authz/roles at request time
  3. On 400, re-fetch the roles list and let the user repick the parent

Example fix

// before
api.post('/authz/roles', { name: 'junior-dev', parent_role_id: savedId });

// after
const roles = await api.get('/authz/roles');
const parent = roles.find(r => r.name === 'developer');
if (!parent) throw new Error('parent role missing');
await api.post('/authz/roles', { name: 'junior-dev', parent_role_id: parent.id });
Defensive patterns

Strategy: validation

Validate before calling

const roles = await api.get('/api/v1/authz/roles');
if (payload.parent_role_id && !roles.some(r => r.id === payload.parent_role_id)) {
  throw new Error('parent role does not exist');
}

Try / catch

catch (e) { if (e.status === 400) { await reloadRoles(); repickParent(); } }

Prevention

When it happens

Trigger: POST {"name": "new-role", "parent_role_id": "<unknown-uuid>"} — parent was deleted, belongs to another install, or the UUID is malformed-but-parseable.

Common situations: Building role hierarchies from exported config where parent roles were not imported first, or referencing a parent deleted by another admin between form load and submit.

Related errors


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