langflow-ai/langflow · error · HTTPException

Unexpected error: {exc!s}

Error message

Unexpected error: {exc!s}

What it means

Final catch-all in the flow-events handler: any exception other than JobQueueNotFoundError and non-HTTPException types is logged with aexception and re-raised as 500 'Unexpected error: {exc!s}'. HTTPExceptions raised inside the inner try are re-raised untouched (explicit isinstance check).

Source

Thrown at src/backend/base/langflow/api/build.py:327

            # Return as NDJSON format - each line is a complete JSON object
            content = "\n".join([event for event in events if event is not None])
            return Response(content=content, media_type="application/x-ndjson")
        except asyncio.CancelledError as exc:
            await logger.ainfo(f"Event polling was cancelled for job {job_id}")
            raise HTTPException(status_code=499, detail="Event polling was cancelled") from exc
        except asyncio.TimeoutError:
            await logger.awarning(f"Timeout while waiting for events for job {job_id}")
            return Response(content="", media_type="application/x-ndjson")  # Return empty response instead of error

    except JobQueueNotFoundError as exc:
        await logger.aerror(f"Job not found: {job_id}. Error: {exc!s}")
        raise HTTPException(status_code=404, detail=f"Job not found: {exc!s}") from exc
    except Exception as exc:
        if isinstance(exc, HTTPException):
            raise
        await logger.aexception(f"Unexpected error processing flow events for job {job_id}")
        raise HTTPException(status_code=500, detail=f"Unexpected error: {exc!s}") from exc


async def create_flow_response(
    queue: asyncio.Queue,
    event_manager: EventManager,
    event_task: asyncio.Task | None,
    *,
    queue_service: JobQueueService | None = None,
    job_id: str | None = None,
) -> DisconnectHandlerStreamingResponse:
    """Create a streaming response for the flow build process.

    When *queue_service* and *job_id* are provided and the service exposes a
    ``signal_cancel`` method (RedisJobQueueService with cancel_channel_enabled),
    a client disconnect on a non-owner worker (``event_task is None``) publishes
    a cross-worker cancel so the producer worker stops emitting events promptly
    instead of running the build to natural completion.
    """

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Read the aexception traceback in the logs — the detail string alone rarely identifies the failing branch.
  2. If it recurs after an upgrade, clear old job/event keys in Redis so stale-schema events are not replayed.
  3. Report with the traceback if the failure is inside Langflow's own event pipeline.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    events = await get_flow_events(job_id)
except HTTPError as e:
    if e.response.status_code == 500 and "Unexpected error" in e.response.text:
        capture_server_logs(job_id)  # aexception logged the real traceback server-side
        raise
    raise

Prevention

When it happens

Trigger: Failures while consuming the event stream: queue decode errors (value.decode('utf-8') on corrupt data), event_manager callback exceptions, asyncio primitives misbehaving, or bugs in delivery-mode-specific branches.

Common situations: Corrupt queue payloads after a version upgrade changed the event schema; bugs in custom event-manager extensions; Redis returning unexpected types.

Related errors


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