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
- To clear all permissions, send {"permissions": []} (empty list)
- To leave permissions unchanged, omit the "permissions" key from the PATCH body
- 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
- Map an empty UI selection to [], never null
- Type the client payload so permissions is string[] | undefined, not string[] | null
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
- name cannot be null
- Unknown permission_level {payload.permission_level!r}
- parent_role_id does not reference an existing role
- A role cannot be its own parent
- Name conflict — another role already uses this name
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/0a447a2ee2731f09.
Report an issue: GitHub.