{"record":{"id":"4dbe4f38797c6f7e","repo":"langflow-ai/langflow","slug":"flow-is-not-public-4dbe4f","errorCode":null,"errorMessage":"Flow is not public","messagePattern":"Flow is not public","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"src/backend/base/langflow/api/v1/flows.py","lineNumber":323,"sourceCode":"\n\n@router.get(\"/public_flow/{flow_id}\", response_model=FlowRead, status_code=200)\nasync def read_public_flow(\n    *,\n    session: DbSession,\n    flow_id: UUID,\n):\n    \"\"\"Read a public flow without requiring authorization (public means public).\n\n    Because this endpoint is unauthenticated, secret field values (every template\n    field marked ``password``) are stripped before returning so a PUBLIC flow does\n    not leak the owner's stored API keys / credentials to anonymous callers.\n    \"\"\"\n    flow = (await session.exec(select(Flow).where(Flow.id == flow_id))).first()\n    if flow is None:\n        raise HTTPException(status_code=404, detail=\"Flow not found\")\n    if flow.access_type is not AccessTypeEnum.PUBLIC:\n        raise HTTPException(status_code=403, detail=\"Flow is not public\")\n    flow_read = FlowRead.model_validate(flow, from_attributes=True)\n    flow_read.data = strip_secret_field_values(flow_read.data)\n    return flow_read\n\n\n@router.patch(\"/{flow_id}\", response_model=FlowRead, status_code=200)\nasync def update_flow(\n    *,\n    session: DbSession,\n    flow_id: UUID,\n    db_flow: AuthorizedWriteFlow,\n    flow: FlowUpdate,\n    current_user: CurrentActiveUser,\n    storage_service: Annotated[StorageService, Depends(get_storage_service)],\n):\n    \"\"\"Update a flow.\"\"\"\n    actor = UserRead.model_validate(current_user, from_attributes=True)\n    try:","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/flows.py#L305-L341","documentation":"403 from the same unauthenticated public-flow endpoint: the Flow row exists but access_type is not PUBLIC. The endpoint intentionally serves anonymous callers, so any non-public flow is refused before serialization — and secret template fields would otherwise leak, which is why the strip step only runs after this gate.","triggerScenarios":"Loading /flows/public/{flow_id} for a flow whose access_type is PRIVATE or SESL (share-link) rather than PUBLIC; or the owner toggled it back to private after the link was shared.","commonSituations":"Users sharing a 'public link' that was actually a share/private link; access_type changed in the UI after the URL was distributed; expecting share-link flows to be loadable on the anonymous endpoint.","solutions":["The owner sets the flow's access to PUBLIC (flow settings / access_type) and the link works anonymously","Or consume the flow with an authenticated request via GET /api/v1/flows/{flow_id} as the owner/shared user","For share-link access, use the share-link route rather than the public endpoint"],"exampleFix":"# before\nflow.access_type = AccessTypeEnum.PRIVATE\n\n# after\nflow.access_type = AccessTypeEnum.PUBLIC\nsession.add(flow)  # link now served anonymously, secrets stripped","handlingStrategy":"type-guard","validationCode":"// Owner-side: verify visibility before distributing an anonymous link\nconst flow = (await axios.get(`/api/v1/flows/${flowId}`)).data;\nconst isPublic = flow.access_type === 'PUBLIC';","typeGuard":"const isPubliclyShared = (f: { access_type?: string } | undefined): f is { access_type: 'PUBLIC' } =>\n  f?.access_type === 'PUBLIC';","tryCatchPattern":"catch (e) { if (e.response?.status === 403) showMakePublicPrompt(flowId); else throw e; }","preventionTips":["Check access_type === 'PUBLIC' in the share UI and warn before copying a non-public link","Remember public flows are anonymous-readable (secrets are stripped server-side) — only publish intentionally","Handle 403 and 404 differently in the UI: 403 means ask the owner, 404 means link is dead"],"tags":["http-403","flows","public-flow","access-type","sharing","security"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}