langchain-ai/langchain · error · RuntimeError

v2 stream finished without producing a message

Error message

v2 stream finished without producing a message

What it means

`RuntimeError` raised in sync `_generate_with_cache` after driving the v2 protocol-event stream to completion: the stream accumulator's `output_message` was still `None`. The v2 streaming path (native event generator or the `_stream` compat bridge) is expected to assemble at least one message; reaching the end without one is an invariant violation.

Source

Thrown at libs/core/langchain_core/language_models/chat_models.py:1951

            **kwargs,
        ):
            stream_accum = ChatModelStream(
                message_id=(
                    f"{LC_ID_PREFIX}-{run_manager.run_id}" if run_manager else None
                )
            )
            assert run_manager is not None  # noqa: S101
            for _event in self._iter_v2_events(
                messages,
                run_manager=run_manager,
                stream=stream_accum,
                stop=stop,
                **kwargs,
            ):
                pass
            if stream_accum.output_message is None:
                msg = "v2 stream finished without producing a message"
                raise RuntimeError(msg)
            result = ChatResult(
                generations=[ChatGeneration(message=stream_accum.output_message)]
            )
        # If stream is not explicitly set, check if implicitly requested by
        # astream_events() or astream_log(). Bail out if _stream not implemented
        elif self._should_stream(
            async_api=False,
            run_manager=run_manager,
            **kwargs,
        ):
            chunks: list[ChatGenerationChunk] = []
            run_id: str | None = (
                f"{LC_ID_PREFIX}-{run_manager.run_id}" if run_manager else None
            )
            yielded = False
            index = -1
            index_type = ""
            for chunk in self._stream(messages, stop=stop, **kwargs):

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Ensure the model's `_stream` (or native event generator) emits at least one message-producing chunk/`message_start`-style event.
  2. Reproduce with v2 streaming disabled (no v2 handlers attached) to confirm the model itself returns a message; if not, fix the model.
  3. Check for upstream API errors that end the stream early — the error may mask the real cause; inspect the raw stream.
  4. Upgrade `langchain-core`: v2 bridge regressions have been fixed across releases.

Example fix

# before
def _stream(self, messages, stop=None, **kw):
    return
    yield  # v2 path ends with output_message None

# after
def _stream(self, messages, stop=None, **kw):
    yield ChatGenerationChunk(message=AIMessageChunk(content=self._generate(messages, stop=stop).generations[0].message.content))
Defensive patterns

Strategy: validation

Validate before calling

def stream_yields_message(model, messages) -> bool:
    for _ in model._stream(messages):
        return True
    return False

Try / catch

try:
    result = model.invoke(messages)
except RuntimeError as e:
    if "v2 stream finished without producing" in str(e):
        # detach v2 handlers / fall back to plain invoke without callbacks
        result = model.invoke(messages, callbacks=None)
    else:
        raise

Prevention

When it happens

Trigger: A v2-opted-in callback handler (`_V2StreamingCallbackHandler`) triggers protocol streaming, but the model's event generator / `_stream` produces no message events — empty streams, streams that only emit non-message events, or a broken compat bridge in a custom subclass.

Common situations: Custom chat models that implement `_stream` but yield nothing for some inputs; providers returning empty completions; LangSmith/tracing handlers that opt into v2 streaming while the model produces zero events.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/a6b23e970edd20c4. Report an issue: GitHub.