langflow-ai/langflow · error · HTTPException
Flow not found
Error message
Flow not found
What it means
404 from GET /api/v1/flow_events/{flow_id}/events (and sibling endpoints using _verify_flow_owner): no Flow row matches the given flow_id where user_id equals the caller OR user_id IS NULL. The lookup deliberately conflates 'does not exist' and 'not yours' into one 404 so flow ids of other users are not distinguishable from random UUIDs.
Solutions
- Re-fetch the caller's flow list (GET /api/v1/flows/) and confirm the flow_id still exists for this user
- If the flow should be shared, have the owner share it or use the authorization plugin's cross-user fetch support instead of this owner-scoped endpoint
- If AUTO_LOGIN is on, confirm which user the session maps to — flows created by a different auto-login user are invisible here
- Handle 404 by refreshing/expiring the stale flow reference in the UI
Example fix
// before
const events = await getFlowEvents(flowId);
// after: treat 404 as 'gone', refresh the flow list
try {
const events = await getFlowEvents(flowId);
} catch (e) {
if (e.response?.status === 404) {
queryClient.invalidateQueries({ queryKey: ['flows'] });
return;
}
throw e;
} Defensive patterns
Strategy: validation
Validate before calling
const { data: flows } = await axios.get('/api/v1/flows/');
const owned = flows.some((f) => f.id === flowId); // only then subscribe to events Try / catch
catch (e) {
if (e.response?.status === 404) { stopEventPolling(flowId); invalidateFlowsQuery(); return; }
throw e;
} Prevention
- Resolve flow_id from the live flows listing before opening long-poll/SSE event streams
- Treat 404 on event endpoints as terminal for the session — stop polling instead of retrying
- In multi-user setups, verify ownership in the UI before exposing event URLs
When it happens
Trigger: Requesting events for a flow id that was deleted, a flow owned by a different user, or a malformed-but-valid UUID that never existed. Also hit when AUTO_LOGIN semantics changed and a flow you expected to be null-owner is actually owned by another auto-created user.
Common situations: Stale client-side flow list after the flow was deleted in another tab/session; copying flow ids between environments (dev id used against prod); multi-user deployments where the flow belongs to someone else.
Related errors
- Flow not found
- An error occurred while uploading the file
- Cannot change a2a_card_overrides of a flow you do not own.
- Cannot change a2a_enabled of a flow you do not own.
- Cannot change folder of a flow you do not own.
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/9f83124737886bd0.
Report an issue: GitHub.
Appendix: source
Thrown at src/backend/base/langflow/api/v1/flow_events.py:42
class FlowEventsResponse(BaseModel):
events: list[FlowEventResponse]
settled: bool
class FlowEventCreate(BaseModel):
type: FLOW_EVENT_TYPES
summary: str = Field(default="", max_length=500)
async def _verify_flow_owner(session: DbSession, flow_id: UUID, user_id: UUID) -> None:
result = await session.exec(
select(Flow).where(
Flow.id == flow_id,
or_(Flow.user_id == user_id, Flow.user_id == None), # noqa: E711
)
)
if not result.first():
raise HTTPException(status_code=404, detail="Flow not found")
@router.get("/{flow_id}/events", response_model=FlowEventsResponse)
async def get_flow_events(
flow_id: UUID,
current_user: CurrentActiveUser,
session: DbSession,
since: Annotated[float, Query(description="UTC timestamp to get events after")] = 0.0,
*,
service: Annotated[FlowEventsService, Depends(get_flow_events_service)],
) -> FlowEventsResponse:
await _verify_flow_owner(session, flow_id, current_user.id)
events, settled = service.get_since(str(flow_id), since)
return FlowEventsResponse(
events=[FlowEventResponse(type=e.type, timestamp=e.timestamp, summary=e.summary) for e in events],
settled=settled,
)
View on GitHub (pinned to 976ec789d2)