{"record":{"id":"40533144f8a59559","repo":"langflow-ai/langflow","slug":"unknown-permission-level-payload-permission-level","errorCode":null,"errorMessage":"Unknown permission_level {payload.permission_level!r}","messagePattern":"Unknown permission_level (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"src/backend/base/langflow/api/v1/authz_shares.py","lineNumber":430,"sourceCode":"        session,\n        resource_type=row.resource_type,\n        resource_id=row.resource_id,\n    )\n    await _ensure_can_administer_share(user=current_user, owner_id=owner_id)\n    # See create_share: owner_id is the *resource* owner so non-owners are\n    # forced through ensure_share_permission's plugin enforce() path.\n    await ensure_share_permission(\n        current_user,\n        ShareAction.UPDATE,\n        share_id=share_id,\n        share_user_id=owner_id,\n    )\n\n    # Validate permission_level (422 before DB CHECK).\n    try:\n        row.permission_level = SharePermissionLevel(payload.permission_level).value\n    except ValueError as exc:\n        raise HTTPException(\n            status_code=400,\n            detail=f\"Unknown permission_level {payload.permission_level!r}\",\n        ) from exc\n    session.add(row)\n    # Rollback + fixed 409 on constraint failure (same as create_share).\n    try:\n        await session.flush()\n    except Exception as exc:\n        await session.rollback()\n        logger.warning(\"authz_share update rejected: %s\", exc)\n        raise HTTPException(\n            status_code=status.HTTP_409_CONFLICT,\n            detail=\"Share could not be updated: it may conflict with an existing share.\",\n        ) from exc\n    await session.refresh(row)\n    response = (await _serialize_shares(session, [row]))[0]\n    await session.commit()\n","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_shares.py#L412-L448","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nawait updateShare(id, { permission_level: 'writer' });\n\n// after\nawait updateShare(id, { permission_level: 'write' }); // per SharePermissionLevel enum","handlingStrategy":"type-guard","validationCode":"const PERMISSION_LEVELS = ['read', 'write']; // mirror SharePermissionLevel from /openapi.json\nif (!PERMISSION_LEVELS.includes(permission_level)) {\n  throw new Error(`invalid permission_level ${permission_level}`);\n}","typeGuard":"type SharePermissionLevel = 'read' | 'write';\nconst isPermissionLevel = (v: unknown): v is SharePermissionLevel =>\n  v === 'read' || v === 'write';","tryCatchPattern":null,"preventionTips":["Drive the permission picker from the OpenAPI enum, not free text","Re-validate enum literals after upgrading Langflow — enum members can change"],"tags":["authz","api","shares","validation","enum","patch"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}