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.

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)

Solutions

  1. Re-fetch the caller's flow list (GET /api/v1/flows/) and confirm the flow_id still exists for this user
  2. 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
  3. If AUTO_LOGIN is on, confirm which user the session maps to — flows created by a different auto-login user are invisible here
  4. 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

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


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/9f83124737886bd0. Report an issue: GitHub.