langchain - ✅(Solved) Fix ChatOpenAI/ChatAnthropic: request_timeout=None (default) disables SDK timeout, causing infinite hangs [5 pull requests, 7 comments, 4 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#35597Fetched 2026-04-08 00:25:21
View on GitHub
Comments
7
Participants
4
Timeline
17
Reactions
0
Timeline (top)
commented ×7cross-referenced ×4mentioned ×2subscribed ×2

Error Message

Error Message and Stack Trace (if applicable)

No error — the process hangs silently. When hitting a network issue or server-side delay, the HTTP request blocks indefinitely with no timeout. The only way to recover is to kill the process (kill -9). In strace, the process shows futex_wait — waiting forever for an HTTP response that will never arrive.

Root Cause

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

PR fix notes

PR #35616: fix(openai): omit timeout from client_params when not set by user

Description (problem / solution / changelog)

When request_timeout is None (the default), we passed timeout=None to the OpenAI SDK, which interprets it as "disable all timeouts" — bypassing the built-in 600s default and causing infinite hangs on network issues.

Now we omit the timeout key entirely when unset, so the SDK default applies. Aligns with langchain-google-genai's existing approach.

Fixes #35597

Changed files

  • libs/partners/openai/langchain_openai/chat_models/base.py (modified, +2/-1)
  • libs/partners/openai/tests/unit_tests/chat_models/test_base.py (modified, +14/-0)

PR #35619: fix(anthropic): omit timeout from client_params when not set by user

Description (problem / solution / changelog)

When default_request_timeout is None (the default), we passed timeout=None to the Anthropic SDK, which interprets it as "disable all timeouts" — bypassing the built-in 600s default and causing infinite hangs on network issues.

Changed the guard in _client_params from is None or > 0 to is not None and > 0 so the key is omitted when unset, letting the SDK default apply. Aligns with langchain-google-genai's existing approach.

Fixes #35597

Changed files

  • libs/partners/anthropic/langchain_anthropic/chat_models.py (modified, +6/-4)
  • libs/partners/anthropic/tests/unit_tests/test_chat_models.py (modified, +12/-0)

PR #35745: fix(openai): prevent request_timeout=None from disabling SDK default timeout

Description (problem / solution / changelog)

Summary

  • request_timeout defaults to None, which gets passed as timeout=None to the OpenAI SDK, disabling its built-in 600s default timeout. This causes requests to hang indefinitely on network issues.
  • Introduces a _TIMEOUT_UNSET sentinel as the default value. When unset, timeout is omitted from client_params entirely, letting the OpenAI SDK use its own default.
  • Users can still pass timeout=None explicitly to disable timeouts if desired.
  • Also handles the httpx client creation paths where request_timeout is passed through.

Fixes #35597

Test plan

  • Verify ChatOpenAI() without timeout arg does not pass timeout=None to SDK
  • Verify ChatOpenAI(timeout=30) still sets a 30s timeout
  • Verify ChatOpenAI(timeout=None) explicitly disables timeout (preserves opt-in behavior)
  • Existing unit tests pass

This PR was developed with AI agent assistance.

Changed files

  • libs/partners/openai/langchain_openai/chat_models/base.py (modified, +18/-9)

PR #459: feat(node): Add documents lane to frame grabber and vision nodes

Description (problem / solution / changelog)

Summary

<!-- Describe your changes in 1-3 bullet points -->
  • Frame grabber now emits image frames as Doc objects — the documents lane is registered in services.json, letting downstream nodes receive frames with chunkId and time_stamp metadata attached.
  • Ollama Vision and Mistral Vision gain a documents lane — both nodes now implement writeDocuments(), accepting Doc(type='Image') from the frame grabber, running vision inference, and re-emitting Doc(type='Text') with the original frame metadata (number, timestamp) preserved.
  • Enables timestamped semantic scene description for video — you can now wire frame_grabber → ollama/mistral vision via the documents lane and get per-frame text descriptions that carry the source timestamp through the pipeline.

Type

<!-- What kind of change is this? (feature, fix, refactor, docs, chore, etc.) -->

feature

Testing

  • Tests added or updated
  • Tested locally
  • ./builder test passes

Checklist

  • Commit messages follow conventional commits
  • No secrets or credentials included
  • Wiki updated (if applicable)
  • Breaking changes documented (if applicable)

Linked Issue

<!-- REQUIRED: Every PR must be linked to an issue. Use one of: --> <!-- Fixes #123 / Closes #123 / Resolves #123 -->

Fixes #

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • New Features

    • Vision nodes now accept and emit "documents" for batch image/document analysis.
    • Frame grabber emits selected frames as documents in addition to images and tables; document outputs preserve frame metadata (frame number, timestamp).
    • Thumbnail node can produce 128×128 thumbnails from image documents for downstream use.
  • Bug Fixes / Reliability

    • Vision model calls now enforce request timeouts and fail faster on hangs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Changed files

  • nodes/src/nodes/frame_grabber/IGlobal.py (modified, +8/-0)
  • nodes/src/nodes/frame_grabber/services.json (modified, +28/-88)
  • nodes/src/nodes/llm_vision_mistral/IInstance.py (modified, +38/-1)
  • nodes/src/nodes/llm_vision_mistral/services.json (modified, +168/-204)
  • nodes/src/nodes/llm_vision_ollama/IInstance.py (modified, +41/-1)
  • nodes/src/nodes/llm_vision_ollama/ollama_vision.py (modified, +34/-10)
  • nodes/src/nodes/llm_vision_ollama/services.json (modified, +40/-112)
  • nodes/src/nodes/thumbnail/IInstance.py (modified, +32/-1)
  • nodes/src/nodes/thumbnail/services.json (modified, +29/-21)

PR #26: feat(digest): LlmProvider interface + OpenRouter impl (#9)

Description (problem / solution / changelog)

Summary

  • Defines the LlmProvider port interface (src/digest/llm/llm-provider.interface.ts) per docs/interfaces.md -- framework-agnostic, no LangChain types in the contract
  • Implements OpenRouterProvider wrapping @langchain/openai ChatOpenAI with baseURL: https://openrouter.ai/api/v1, HTTP-Referer and X-Title headers per OpenRouter conventions
  • Returns { content, usage: { tokensIn, tokensOut } } with token counts from the OpenRouter response metadata
  • Adds createLlmProvider(env) factory in src/digest/llm/index.ts dispatching on LLM_PROVIDER env var
  • Wires LlmModule.forRoot(env) into AppModule with LLM_PROVIDER DI token for injection
  • Makes OPENROUTER_API_KEY required in src/config/env.ts (milestone #9 boundary)
  • Bumps version from 0.6.0 to 0.7.0

Test plan

  • Unit tests for OpenRouterProvider with mocked ChatOpenAI -- verifies constructor config, message building, response format passthrough, temperature/maxTokens binding, missing usage fallback, and multi-turn conversations
  • Unit tests for createLlmProvider factory -- verifies OpenRouter dispatch and unknown provider error
  • Updated env.test.ts with tests for required OPENROUTER_API_KEY and LLM defaults
  • Updated app.module.test.ts, appwrite.service.test.ts, logger.test.ts to include required OPENROUTER_API_KEY
  • bunx tsc --noEmit passes clean
  • bunx biome lint . -- no new warnings (all warnings are pre-existing)
  • bun test -- 288 pass, 1 pre-existing fail (IngestionModule, needs Redis)

Closes #9

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

Summary by CodeRabbit

  • New Features

    • Integrated LLM-powered chat support with text/JSON response modes, usage reporting, and OpenRouter as the default provider.
  • Tests

    • Added unit and integration tests for provider selection, request shaping, response parsing, and error scenarios.
  • Chores

    • Added runtime LLM dependencies and updated env example; OPENROUTER_API_KEY is now required.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Changed files

  • .env.example (modified, +1/-1)
  • bun.lock (modified, +65/-1)
  • package.json (modified, +2/-0)
  • src/app.module.test.ts (modified, +4/-0)
  • src/app.module.ts (modified, +3/-1)
  • src/appwrite/appwrite.service.test.ts (modified, +1/-0)
  • src/common/logger.test.ts (modified, +1/-0)
  • src/config/env.test.ts (modified, +21/-1)
  • src/config/env.ts (modified, +4/-2)
  • src/digest/llm/index.ts (added, +5/-0)
  • src/digest/llm/llm-factory.test.ts (added, +43/-0)
  • src/digest/llm/llm-provider.interface.ts (added, +32/-0)
  • src/digest/llm/llm.factory.ts (added, +19/-0)
  • src/digest/llm/llm.module.ts (added, +28/-0)
  • src/digest/llm/llm.tokens.ts (added, +13/-0)
  • src/digest/llm/openrouter.provider.test.ts (added, +249/-0)
  • src/digest/llm/openrouter.provider.ts (added, +98/-0)

Code Example

from openai._utils import is_given
from openai._types import NOT_GIVEN
import openai
import httpx

# Step 1: ChatOpenAI defaults request_timeout to None
from langchain_openai import ChatOpenAI
print(ChatOpenAI.model_fields["request_timeout"].default)  # None

# Step 2: LangChain passes timeout=None to openai.OpenAI()
# In ChatOpenAI.validate_environment() (line ~1005):
#   client_params = {"timeout": self.request_timeout, ...}
# When request_timeout=None -> openai.OpenAI(timeout=None)

# Step 3: OpenAI SDK treats None as "explicitly no timeout"
print(is_given(None))       # True  -> SDK treats this as an explicit value
print(is_given(NOT_GIVEN))  # False -> only NOT_GIVEN triggers SDK defaults

# Step 4: SDK default (600s) is bypassed
print(openai.DEFAULT_TIMEOUT)
# Timeout(connect=5.0, read=600, write=600, pool=600)
# This default is ONLY applied when timeout is NOT_GIVEN, not when it's None

# Step 5: httpx receives timeout=None -> no timeout at all
print(httpx.Timeout(None))
# Timeout(timeout=None) -> connect=None, read=None, write=None, pool=None

# Same issue exists for ChatAnthropic:
from langchain_anthropic import ChatAnthropic
print(ChatAnthropic.model_fields["default_request_timeout"].default)  # None
# Line ~291: if self.default_request_timeout is None or self.default_request_timeout > 0:
#                client_params["timeout"] = self.default_request_timeout
# -> anthropic.Anthropic(timeout=None) -> same infinite hang

---

client_params: dict = {
    "timeout": self.request_timeout,  # None by default -> passed as-is
    ...
}

---

if self.default_request_timeout is None or self.default_request_timeout > 0:
    client_params["timeout"] = self.default_request_timeout  # None -> passed as-is

---

client_params: dict = {
    "organization": self.openai_organization,
    "base_url": self.openai_api_base,
    "default_headers": self.default_headers,
    "default_query": self.default_query,
}
if self.request_timeout is not None:
    client_params["timeout"] = self.request_timeout

---

if self.default_request_timeout is not None and self.default_request_timeout > 0:
    client_params["timeout"] = self.default_request_timeout

---

System Information
------------------
> OS:  Linux
> Python Version:  3.12.3

Package Information
-------------------
> langchain_core: 1.2.17
> langchain: 1.2.10
> langchain_anthropic: 1.3.4
> langchain_openai: 1.1.10
> langchain_google_genai: 4.2.1
> langchain_ollama: 1.0.1

Other Dependencies
------------------
> anthropic: 0.84.0
> httpx: 0.28.1
> openai: 2.24.0
> pydantic: 2.12.5
RAW_BUFFERClick to expand / collapse

Checked other resources

  • 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

Package

langchain-openai, langchain-anthropic

Related Issues / PRs

Reproduction Steps / Example Code (Python)

from openai._utils import is_given
from openai._types import NOT_GIVEN
import openai
import httpx

# Step 1: ChatOpenAI defaults request_timeout to None
from langchain_openai import ChatOpenAI
print(ChatOpenAI.model_fields["request_timeout"].default)  # None

# Step 2: LangChain passes timeout=None to openai.OpenAI()
# In ChatOpenAI.validate_environment() (line ~1005):
#   client_params = {"timeout": self.request_timeout, ...}
# When request_timeout=None -> openai.OpenAI(timeout=None)

# Step 3: OpenAI SDK treats None as "explicitly no timeout"
print(is_given(None))       # True  -> SDK treats this as an explicit value
print(is_given(NOT_GIVEN))  # False -> only NOT_GIVEN triggers SDK defaults

# Step 4: SDK default (600s) is bypassed
print(openai.DEFAULT_TIMEOUT)
# Timeout(connect=5.0, read=600, write=600, pool=600)
# This default is ONLY applied when timeout is NOT_GIVEN, not when it's None

# Step 5: httpx receives timeout=None -> no timeout at all
print(httpx.Timeout(None))
# Timeout(timeout=None) -> connect=None, read=None, write=None, pool=None

# Same issue exists for ChatAnthropic:
from langchain_anthropic import ChatAnthropic
print(ChatAnthropic.model_fields["default_request_timeout"].default)  # None
# Line ~291: if self.default_request_timeout is None or self.default_request_timeout > 0:
#                client_params["timeout"] = self.default_request_timeout
# -> anthropic.Anthropic(timeout=None) -> same infinite hang

Error Message and Stack Trace (if applicable)

No error — the process hangs silently. When hitting a network issue or server-side delay, the HTTP request blocks indefinitely with no timeout. The only way to recover is to kill the process (kill -9). In strace, the process shows futex_wait — waiting forever for an HTTP response that will never arrive.

Description

Problem

When users create a ChatOpenAI or ChatAnthropic instance without explicitly setting request_timeout, the default value None is passed through to the underlying SDK (openai.OpenAI(timeout=None) / anthropic.Anthropic(timeout=None)).

Both the OpenAI and Anthropic SDKs distinguish between:

  • NOT_GIVEN → "user didn't set this" → SDK default timeout applies (600s read)
  • None → "user explicitly wants no timeout" → httpx.Timeout(None) → infinite

LangChain uses None to mean "not configured", but the SDKs interpret None as "explicitly disable all timeouts". This semantic mismatch causes every default LangChain installation to run without any HTTP timeout.

Impact

ProviderLangChain defaultSDK default (bypassed)Effective timeout
ChatOpenAIrequest_timeout=None600s readinfinite
ChatAnthropicdefault_request_timeout=None600s readinfinite
ChatGoogleGenerativeAItimeout=Noneunknowninfinite

Any network glitch, load balancer timeout, or server-side hang causes the process to block forever. This is especially critical in autonomous/agentic loops where there is no human to notice and kill the process.

Observed in production

During an autonomous agent loop using ChatOpenAI against a local llama-server (OpenAI-compatible API), the process hung after 38 successful LLM calls. Server-side monitoring confirmed the server had finished generating (EOS after 180 tokens), but the client never closed the connection. The httpx client waited indefinitely because timeout=None.

Root cause in code

langchain-openai (ChatOpenAI.validate_environment, line ~1005):

client_params: dict = {
    "timeout": self.request_timeout,  # None by default -> passed as-is
    ...
}

langchain-anthropic (ChatAnthropic.validate_environment, line ~291):

if self.default_request_timeout is None or self.default_request_timeout > 0:
    client_params["timeout"] = self.default_request_timeout  # None -> passed as-is

Suggested fix

When request_timeout is None (not explicitly set by the user), omit the timeout key from client_params so the SDK defaults apply:

For langchain-openai:

client_params: dict = {
    "organization": self.openai_organization,
    "base_url": self.openai_api_base,
    "default_headers": self.default_headers,
    "default_query": self.default_query,
}
if self.request_timeout is not None:
    client_params["timeout"] = self.request_timeout

For langchain-anthropic:

if self.default_request_timeout is not None and self.default_request_timeout > 0:
    client_params["timeout"] = self.default_request_timeout

This is a one-line change per provider that restores the SDK's built-in 600s timeout for all users who haven't explicitly configured a timeout.

System Info

System Information
------------------
> OS:  Linux
> Python Version:  3.12.3

Package Information
-------------------
> langchain_core: 1.2.17
> langchain: 1.2.10
> langchain_anthropic: 1.3.4
> langchain_openai: 1.1.10
> langchain_google_genai: 4.2.1
> langchain_ollama: 1.0.1

Other Dependencies
------------------
> anthropic: 0.84.0
> httpx: 0.28.1
> openai: 2.24.0
> pydantic: 2.12.5

extent analysis

Problem Summary Fix the infinite hang when creating ChatOpenAI or ChatAnthropic instances without explicitly setting request_timeout.

Root Cause Analysis The issue arises from the semantic mismatch between LangChain's None (meaning "not configured") and the SDKs' interpretation of None as "explicitly disable all timeouts".

Fix Plan Update langchain-openai and langchain-anthropic to omit the timeout key from client_params when request_timeout is None:

langchain-openai

client_params: dict = {
    "organization": self.openai_organization,
    "base_url": self.openai_api_base,
    "default_headers": self.default_headers,
    "default_query": self.default_query,
}
if self.request_timeout is not None:
    client_params["timeout"] = self.request_timeout

langchain-anthropic

if self.default_request_timeout is not None and self.default_request_timeout > 0:
    client_params["timeout"] = self.default_request_timeout

Verification

  1. Create a ChatOpenAI or ChatAnthropic instance without explicitly setting request_timeout.
  2. Verify that the timeout key is not present in client_params.
  3. Test the instance with a network glitch or server-side delay to ensure the process times out correctly.

Extra Tips

  • Update to the latest stable version of LangChain to ensure you have the fix.
  • Consider adding a default timeout value to request_timeout to prevent infinite hangs in the future.
  • Review the SDK documentation to understand their timeout behavior and ensure you're using the correct values.

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