{"record":{"id":"34b0788505838d9d","repo":"langflow-ai/langflow","slug":"you-don-t-have-permission-to-edit-this-flow","errorCode":null,"errorMessage":"You don't have permission to edit this flow.","messagePattern":"You don't have permission to edit this flow\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"src/backend/base/langflow/api/v1/authz_route_dependencies.py","lineNumber":54,"sourceCode":"            flow_user_id=flow.user_id,\n            workspace_id=flow.workspace_id,\n            folder_id=flow.folder_id,\n        )\n    except HTTPException as exc:\n        if act in (FlowAction.WRITE, FlowAction.DELETE) and exc.status_code == status.HTTP_403_FORBIDDEN:\n            try:\n                await ensure_flow_permission(\n                    current_user,\n                    FlowAction.READ,\n                    flow_id=flow_id,\n                    flow_user_id=flow.user_id,\n                    workspace_id=flow.workspace_id,\n                    folder_id=flow.folder_id,\n                )\n            except HTTPException as read_exc:\n                raise deny_to_404(read_exc, detail=\"Flow not found\") from read_exc\n            denied_detail = _FLOW_WRITE_DENIED_DETAIL if act == FlowAction.WRITE else _FLOW_DELETE_DENIED_DETAIL\n            raise HTTPException(status_code=403, detail=denied_detail) from exc\n        raise deny_to_404(exc, detail=\"Flow not found\") from exc\n    return flow\n\n\nasync def get_authorized_flow_for_read(\n    flow_id: UUID,\n    current_user: CurrentActiveUser,\n    session: DbSession,\n) -> Flow:\n    \"\"\"Return a flow the caller may read (404 when denied or missing).\"\"\"\n    return await _get_authorized_flow(FlowAction.READ, flow_id=flow_id, current_user=current_user, session=session)\n\n\nasync def get_authorized_flow_for_write(\n    flow_id: UUID,\n    current_user: CurrentActiveUser,\n    session: DbSession,\n) -> Flow:","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_route_dependencies.py#L36-L72","documentation":"Raised by _get_authorized_flow when the caller requests FlowAction.WRITE but ensure_flow_permission denies it, AND a follow-up READ check succeeds (i.e. you can see the flow but not modify it). In that case the route returns an honest 403 with this message instead of hiding the flow as a 404. Requires superuser/owner-style write access being absent while read access exists (e.g. a viewer-level share or plugin grant).","triggerScenarios":"PATCH/PUT a flow when the caller holds only a read-level share or a plugin grant of read but not write on flow:{id} or its project/workspace domain.","commonSituations":"Collaborator given viewer permission trying to edit; plugin role mapped to read-only on the project domain; assuming share visibility implies edit rights.","solutions":["Ask the owner to grant write (e.g. a share with a write-capable permission_level, or a plugin role with flow:write)","Check your effective grants before editing (plugin audit/share listing) and disable edit UI when only read is held","Fork/copy the flow into your own workspace if edit rights cannot be granted"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await saveFlow(flowId, data);\n} catch (e) {\n  if (e.status === 403 && e.detail.includes('edit')) {\n    showToast('Read-only access — ask the owner for write permission');\n    setReadOnlyMode(true);\n  } else throw e;\n}","preventionTips":["Track the caller's effective permission (from the share/plugin) and switch the UI to read-only proactively","Do not assume a viewable flow is editable"],"tags":["authz","api","flows","forbidden","rbac"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}