langflow-ai/langflow · error · HTTPException
Flow is not public
Error message
Flow is not public
What it means
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.
Source
Thrown at src/backend/base/langflow/api/v1/flows.py:323
@router.get("/public_flow/{flow_id}", response_model=FlowRead, status_code=200)
async def read_public_flow(
*,
session: DbSession,
flow_id: UUID,
):
"""Read a public flow without requiring authorization (public means public).
Because this endpoint is unauthenticated, secret field values (every template
field marked ``password``) are stripped before returning so a PUBLIC flow does
not leak the owner's stored API keys / credentials to anonymous callers.
"""
flow = (await session.exec(select(Flow).where(Flow.id == flow_id))).first()
if flow is None:
raise HTTPException(status_code=404, detail="Flow not found")
if flow.access_type is not AccessTypeEnum.PUBLIC:
raise HTTPException(status_code=403, detail="Flow is not public")
flow_read = FlowRead.model_validate(flow, from_attributes=True)
flow_read.data = strip_secret_field_values(flow_read.data)
return flow_read
@router.patch("/{flow_id}", response_model=FlowRead, status_code=200)
async def update_flow(
*,
session: DbSession,
flow_id: UUID,
db_flow: AuthorizedWriteFlow,
flow: FlowUpdate,
current_user: CurrentActiveUser,
storage_service: Annotated[StorageService, Depends(get_storage_service)],
):
"""Update a flow."""
actor = UserRead.model_validate(current_user, from_attributes=True)
try:View on GitHub (pinned to 976ec789d2)
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
Example fix
# before flow.access_type = AccessTypeEnum.PRIVATE # after flow.access_type = AccessTypeEnum.PUBLIC session.add(flow) # link now served anonymously, secrets stripped
Defensive patterns
Strategy: type-guard
Validate before calling
// Owner-side: verify visibility before distributing an anonymous link
const flow = (await axios.get(`/api/v1/flows/${flowId}`)).data;
const isPublic = flow.access_type === 'PUBLIC'; Type guard
const isPubliclyShared = (f: { access_type?: string } | undefined): f is { access_type: 'PUBLIC' } =>
f?.access_type === 'PUBLIC'; Try / catch
catch (e) { if (e.response?.status === 403) showMakePublicPrompt(flowId); else throw e; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Flow not found
- Cannot transfer ownership of a flow you do not own.
- Invalid filename
- Flow is not public
- Flow is not accessible
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/4dbe4f38797c6f7e.
Report an issue: GitHub.