langflow-ai/langflow · warning · HTTPException
Unknown permission_level {payload.permission_level!r}
Error message
Unknown permission_level {payload.permission_level!r} What it means
Raised by PATCH /api/v1/authz/shares/{share_id} when payload.permission_level is not a valid SharePermissionLevel enum member. The route validates by constructing SharePermissionLevel(value) before touching the DB, so a ValueError becomes a 400 with the bad value echoed — an early, clear rejection ahead of the DB CHECK constraint.
Source
Thrown at src/backend/base/langflow/api/v1/authz_shares.py:430
session,
resource_type=row.resource_type,
resource_id=row.resource_id,
)
await _ensure_can_administer_share(user=current_user, owner_id=owner_id)
# See create_share: owner_id is the *resource* owner so non-owners are
# forced through ensure_share_permission's plugin enforce() path.
await ensure_share_permission(
current_user,
ShareAction.UPDATE,
share_id=share_id,
share_user_id=owner_id,
)
# Validate permission_level (422 before DB CHECK).
try:
row.permission_level = SharePermissionLevel(payload.permission_level).value
except ValueError as exc:
raise HTTPException(
status_code=400,
detail=f"Unknown permission_level {payload.permission_level!r}",
) from exc
session.add(row)
# Rollback + fixed 409 on constraint failure (same as create_share).
try:
await session.flush()
except Exception as exc:
await session.rollback()
logger.warning("authz_share update rejected: %s", exc)
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Share could not be updated: it may conflict with an existing share.",
) from exc
await session.refresh(row)
response = (await _serialize_shares(session, [row]))[0]
await session.commit()
View on GitHub (pinned to 976ec789d2)
Solutions
- Use only permission_level values from the API's OpenAPI schema (SharePermissionLevel enum)
- Restrict the client to a dropdown sourced from /openapi.json instead of free text
- If the level came from an older API version, map it to the current enum before sending
Example fix
// before
await updateShare(id, { permission_level: 'writer' });
// after
await updateShare(id, { permission_level: 'write' }); // per SharePermissionLevel enum Defensive patterns
Strategy: type-guard
Validate before calling
const PERMISSION_LEVELS = ['read', 'write']; // mirror SharePermissionLevel from /openapi.json
if (!PERMISSION_LEVELS.includes(permission_level)) {
throw new Error(`invalid permission_level ${permission_level}`);
} Type guard
type SharePermissionLevel = 'read' | 'write'; const isPermissionLevel = (v: unknown): v is SharePermissionLevel => v === 'read' || v === 'write';
Prevention
- Drive the permission picker from the OpenAPI enum, not free text
- Re-validate enum literals after upgrading Langflow — enum members can change
When it happens
Trigger: PATCH /authz/shares/{id} with {"permission_level": "owner"} or "rw" or any string not in the SharePermissionLevel members (e.g. valid ones like read/write style levels defined by the enum).
Common situations: Client hardcoded strings drifting from the enum after a Langflow upgrade; copy-pasting levels from other systems (Google-style 'writer' vs this API's levels); sending numeric levels to a string enum.
Related errors
- Unknown scope {scope!r}
- name cannot be null
- permissions cannot be null; pass an empty list to clear
- Resource not found
- Share could not be updated: it may conflict with an existing
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/40533144f8a59559.
Report an issue: GitHub.