langflow-ai/langflow · warning · HTTPException
Job not found
Error message
Job not found
What it means
Raised as HTTP 404 with static detail 'Job not found' by _assert_public_job when queue_service.is_public_job_async(job_id) returns False — the job id was never registered through the public build path. The static message is deliberate: reflecting the job_id or returning 403 would confirm which ids exist under other access tiers, leaking information about private builds.
Source
Thrown at src/backend/base/langflow/api/v1/chat.py:978
return await get_flow_events_response(
job_id=job_id,
queue_service=queue_service,
event_delivery=event_delivery,
)
async def _assert_public_job(job_id: str, queue_service: JobQueueService) -> None:
"""Raise HTTP 404 if job_id was not registered through the public build endpoint.
Prevents unauthenticated callers from reading or cancelling private-flow
builds by guessing or leaking a job_id.
Why 404 not 403: returning 403 would confirm the job exists under a different
access tier, leaking information about private builds. 404 is neutral.
"""
if not await queue_service.is_public_job_async(job_id):
# Static detail — do not reflect job_id back; avoid confirming which IDs exist.
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Job not found")
@router.get("/build_public_tmp/{job_id}/events")
async def get_build_events_public(
job_id: str,
queue_service: Annotated[JobQueueService, Depends(get_queue_service)],
*,
event_delivery: EventDeliveryType = EventDeliveryType.STREAMING,
):
"""Get events for a public flow build job.
This endpoint does not require authentication, matching the public build endpoint.
It is used by the shareable playground to consume build events.
"""
await _assert_public_job(job_id, queue_service)
return await get_flow_events_response(
job_id=job_id,
queue_service=queue_service,View on GitHub (pinned to 976ec789d2)
Solutions
- Only use job ids returned by the public build endpoint itself, with public (share) flows.
- For authenticated builds, use the authenticated events/cancel endpoints, not the public ones.
- Open the events stream promptly after starting the public build so the marker is still live.
- Treat 404 as 'not a public job' — do not retry the same id; start a new public build instead.
Defensive patterns
Strategy: validation
Validate before calling
# Only call public endpoints with ids from the public build path
assert job_id.startswith("public-") or job_id in known_public_job_ids, "Not a public job" Try / catch
try:
res = await client.get(f"/api/v1/chat/build_public_tmp/{job_id}/events")
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
stop_polling(job_id) # static detail; id is not a public job, do not retry
return
raise Prevention
- Never use authenticated builds' job ids on public endpoints (and vice versa).
- Open the events stream immediately after the public build starts.
- Remember 404 is intentionally uninformative — it also masks private jobs.
When it happens
Trigger: Hitting GET /build_public_tmp/{job_id}/events or the public cancel endpoint with: a private build's job_id, a guessed/random id, or a public job id whose marker expired in Redis.
Common situations: Attempting to read or cancel another user's build by replaying a leaked job_id; job marker TTL expiring before the events stream is opened; Redis flush removing public markers.
Related errors
AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14).
Data as JSON: /api/errors/7e5724584ae5ff06.
Report an issue: GitHub.