langchain - ✅(Solved) Fix fix(ollama): OllamaLLM streaming uses stop sequences as finish_reason [1 pull requests, 1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
langchain-ai/langchain#37370Fetched 2026-05-14 03:28:49
View on GitHub
Comments
1
Participants
1
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
labeled ×3cross-referenced ×2commented ×1issue_type_added ×1

OllamaLLM._stream and _astream currently use self.stop as generation_info["finish_reason"] for every streamed chunk. This is incorrect because self.stop contains user-provided stop sequences, not the reason the model finished generating. As a result, finish_reason can be None or a list like ["END"] instead of an expected string such as "stop" or "length". Ollama provides the real finish reason as done_reason, but only on the final streamed response.

Error Message

Error Message and Stack Trace (if applicable)

Root Cause

for chunk in llm.stream("Say hi"): gen_info = getattr(chunk, "generation_info", None) print(repr(gen_info))

Observed:

{'finish_reason': ['END'], ...} <- list, not str

Or, if stop is unset:

{'finish_reason': None, ...} <- None on every chunk

Expected:

finish_reason is a string ("stop" / "length" / "tool_calls" / ...)

from Ollama's done_reason, and is set only on the final chunk.

Fix Action

Fix / Workaround

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Other Dependencies

httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.2.0 orjson: 3.11.9 packaging: 26.2 pydantic: 2.13.4 pyyaml: 6.0.3 requests: 2.34.0 requests-toolbelt: 1.0.0 tenacity: 9.1.4 typing-extensions: 4.15.0 uuid-utils: 0.15.0 xxhash: 3.7.0 zstandard: 0.25.0

PR fix notes

PR #37371: fix(ollama): use Ollama done_reason for stream finish_reason

Description (problem / solution / changelog)

Fixes #37370

This fixes how OllamaLLM._stream and _astream populate generation_info["finish_reason"].

Previously, both methods used self.stop as the finish reason for every streamed chunk. But self.stop contains the user-provided stop sequences, not the actual reason why the model finished generating.

This could lead to confusing or invalid metadata. For example, when stop=["END"] is set, finish_reason becomes ["END"] instead of a string like "stop". When no stop sequences are configured, finish_reason is None on every chunk, so downstream telemetry can lose the completion signal.

Ollama already provides the real finish reason as done_reason on the final streamed response. This change uses that value only when the stream is done, and leaves intermediate chunks without a finish reason. The same fix is applied to both sync and async streaming paths.

Changed files

  • libs/partners/ollama/langchain_ollama/llms.py (modified, +6/-4)

Code Example

# Requires a local Ollama daemon serving a model (e.g. `ollama pull llama3.2`).
from langchain_ollama import OllamaLLM

llm = OllamaLLM(model="llama3.2", stop=["END"])

for chunk in llm.stream("Say hi"):
    gen_info = getattr(chunk, "generation_info", None)
    print(repr(gen_info))
# Observed:
#   {'finish_reason': ['END'], ...}            <- list, not str
# Or, if `stop` is unset:
#   {'finish_reason': None, ...}               <- None on every chunk
# Expected:
#   finish_reason is a string ("stop" / "length" / "tool_calls" / ...)
#   from Ollama's `done_reason`, and is set only on the final chunk.

---
RAW_BUFFERClick to expand / collapse

Submission checklist

  • This is a bug, not a usage question.
  • I added a clear and descriptive title that summarizes this issue.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangChain rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
  • This is not related to the langchain-community package.
  • I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.

Package (Required)

  • langchain
  • langchain-openai
  • langchain-anthropic
  • langchain-classic
  • langchain-core
  • langchain-model-profiles
  • langchain-tests
  • langchain-text-splitters
  • langchain-chroma
  • langchain-deepseek
  • langchain-exa
  • langchain-fireworks
  • langchain-groq
  • langchain-huggingface
  • langchain-mistralai
  • langchain-nomic
  • langchain-ollama
  • langchain-openrouter
  • langchain-perplexity
  • langchain-qdrant
  • langchain-xai
  • Other / not sure / general

Related Issues / PRs

PR https://github.com/langchain-ai/langchain/pull/37371 (Please re-open, if it possible, I will fix Ruff (E501) and add tests.)

Reproduction Steps / Example Code (Python)

# Requires a local Ollama daemon serving a model (e.g. `ollama pull llama3.2`).
from langchain_ollama import OllamaLLM

llm = OllamaLLM(model="llama3.2", stop=["END"])

for chunk in llm.stream("Say hi"):
    gen_info = getattr(chunk, "generation_info", None)
    print(repr(gen_info))
# Observed:
#   {'finish_reason': ['END'], ...}            <- list, not str
# Or, if `stop` is unset:
#   {'finish_reason': None, ...}               <- None on every chunk
# Expected:
#   finish_reason is a string ("stop" / "length" / "tool_calls" / ...)
#   from Ollama's `done_reason`, and is set only on the final chunk.

Error Message and Stack Trace (if applicable)

Description

OllamaLLM._stream and _astream currently use self.stop as generation_info["finish_reason"] for every streamed chunk. This is incorrect because self.stop contains user-provided stop sequences, not the reason the model finished generating. As a result, finish_reason can be None or a list like ["END"] instead of an expected string such as "stop" or "length". Ollama provides the real finish reason as done_reason, but only on the final streamed response.

System Info

System Information

OS: Linux OS Version: #29~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Jun 26 14:16:59 UTC 2 Python Version: 3.12.3 (main, Mar 23 2026, 19:04:32) [GCC 13.3.0]

Package Information

langchain_core: 1.4.0 langchain: 1.3.0 langsmith: 0.8.3 langchain_protocol: 0.0.15 langgraph_sdk: 0.3.14

Optional packages not installed

deepagents deepagents-cli

Other Dependencies

httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.2.0 orjson: 3.11.9 packaging: 26.2 pydantic: 2.13.4 pyyaml: 6.0.3 requests: 2.34.0 requests-toolbelt: 1.0.0 tenacity: 9.1.4 typing-extensions: 4.15.0 uuid-utils: 0.15.0 xxhash: 3.7.0 zstandard: 0.25.0

Thank you for your time!

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

langchain - ✅(Solved) Fix fix(ollama): OllamaLLM streaming uses stop sequences as finish_reason [1 pull requests, 1 comments, 1 participants]