langflow-ai/langflow · error · HTTPException

permissions cannot be null; pass an empty list to clear

Error message

permissions cannot be null; pass an empty list to clear

What it means

Raised by PATCH /api/v1/authz/roles/{role_id} when the request body explicitly sets "permissions" to null. The permissions column is nullable=False (with a default_factory of an empty list), so a null would violate the constraint at commit time. The route rejects it up front with a 400 and tells you the idiomatic clear: an empty list.

Source

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

        role.description = payload.description

    if "name" in fields_set:
        # name is NOT NULL + unique on the DB side; reject an explicit null at
        # the boundary so the caller gets a clear 400 instead of an opaque
        # IntegrityError that the catch block below mislabels as "Name conflict".
        if payload.name is None:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="name cannot be null",
            )
        role.name = payload.name

    if "permissions" in fields_set:
        # permissions column is nullable=False (default_factory=list). An empty
        # list is the natural "clear" — None would violate the constraint at
        # commit, so reject it up front.
        if payload.permissions is None:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="permissions cannot be null; pass an empty list to clear",
            )
        role.permissions = list(payload.permissions)

    role.updated_at = datetime.now(timezone.utc)

    try:
        await session.commit()
    except IntegrityError as exc:
        await session.rollback()
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="Name conflict — another role already uses this name",
        ) from exc
    await session.refresh(role)
    await safe_invalidate_role(get_authorization_service(), role.id, op="role:update")
    await audit_decision(

View on GitHub (pinned to 976ec789d2)

Solutions

  1. To clear all permissions, send {"permissions": []} (empty list)
  2. To leave permissions unchanged, omit the "permissions" key from the PATCH body
  3. Fix client serialization to emit [] for empty permission sets rather than null

Example fix

// before
{ "permissions": null }

// after
{ "permissions": [] }
Defensive patterns

Strategy: validation

Validate before calling

function buildPermissionsPatch(perms: string[] | null | undefined) {
  if (perms === undefined) return {}; // unchanged
  if (perms === null) throw new Error('permissions cannot be null — pass [] to clear');
  return { permissions: perms };
}

Type guard

const isPermissionList = (p: unknown): p is string[] =>
  Array.isArray(p) && p.every(x => typeof x === 'string');

Prevention

When it happens

Trigger: PATCH /authz/roles/{id} with body {"permissions": null}; clients that send the whole RoleUpdate object with nulls for collections they meant to leave untouched.

Common situations: UI toggle that removes all permission checkboxes and serializes the empty selection as null instead of []; serializers that emit null for empty arrays; misunderstanding that permissions is a required list, not an optional field.

Related errors


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