langchain - ✅(Solved) Fix langchain-openai: _consolidate_calls raises UnboundLocalError for unrecognized server tool names [2 pull requests, 7 comments, 5 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#36140Fetched 2026-04-08 01:07:59
View on GitHub
Comments
7
Participants
5
Timeline
13
Reactions
0
Assignees
Timeline (top)
commented ×6cross-referenced ×2labeled ×2referenced ×2

_consolidate_calls in _compat.py matches pairs of server_tool_call + server_tool_result items and collapses them into the Responses API format. It handles web_search, file_search, code_interpreter, remote_mcp, and mcp_list_tools by name, but if the tool name doesn't match any of these (e.g. computer, image_generation, or any future server tool), collapsed is never assigned and yield collapsed raises UnboundLocalError.

Also, line 314 uses if instead of elif for file_search, which means for every web_search call, the code unnecessarily evaluates the file_search condition and the entire elif chain that follows.

Error Message

from langchain_openai.chat_models._compat import _consolidate_calls

items = [ {"type": "server_tool_call", "name": "computer", "id": "call_1"}, {"type": "server_tool_result", "tool_call_id": "call_1", "output": "result"}, ] list(_consolidate_calls(items))

UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value

Root Cause

_consolidate_calls in _compat.py matches pairs of server_tool_call + server_tool_result items and collapses them into the Responses API format. It handles web_search, file_search, code_interpreter, remote_mcp, and mcp_list_tools by name, but if the tool name doesn't match any of these (e.g. computer, image_generation, or any future server tool), collapsed is never assigned and yield collapsed raises UnboundLocalError.

Also, line 314 uses if instead of elif for file_search, which means for every web_search call, the code unnecessarily evaluates the file_search condition and the entire elif chain that follows.

Fix Action

Fix

  1. Add a fallback branch for unrecognized tool names that emits both items unchanged (matching the existing "not a matching pair" behavior)
  2. Change if current.get("name") == "file_search": to elif for consistency with the rest of the chain

PR fix notes

PR #36163: fix: fix UnboundLocalError in _consolidate_calls for unrecognized tools

Description (problem / solution / changelog)

Problem

_consolidate_calls in _compat.py matches pairs of server_tool_call and server_tool_result items and collapses them into the Responses API format.

It handles web_search, file_search, code_interpreter, remote_mcp, and mcp_list_tools by name. However, if the tool name doesn't match any of these (e.g., computer, image_generation, or any future server tool), the collapsed variable is never assigned, causing UnboundLocalError when yield collapsed is reached.

Also, line 314 uses if instead of elif for file_search, which means for every web_search call, the code unnecessarily evaluates the file_search condition and the entire elif chain that follows.

Changes

  1. Fix ifelif for file_search branch (line 314)
  2. Add fallback else branch for unrecognized tool names that emits both items unchanged (matching the existing "not a matching pair" behavior)

Testing

  • Unrecognized server tools now pass through unchanged instead of crashing
  • No change to behavior for known tool types

Fixes #36140

Changed files

  • libs/partners/openai/langchain_openai/chat_models/_compat.py (modified, +5/-2)

PR #36187: fix(openai): handle unrecognized server tool names in _consolidate_calls

Description (problem / solution / changelog)

Summary

Fixes #36140

_consolidate_calls crashes with UnboundLocalError when a server_tool_call has a name not in the known set (web_search, file_search, code_interpreter, remote_mcp, mcp_list_tools). This affects any new or unrecognized server tool types (e.g. computer, image_generation) during v1 → Responses API format conversion.

Changes:

  • Add fallback else branch for unrecognized tool names that emits both items unchanged (matching the existing "not a matching pair" behavior)
  • Change second if to elif for file_search to avoid redundant condition evaluation on every web_search call

Repro before fix:

from langchain_openai.chat_models._compat import _consolidate_calls

items = [
    {"type": "server_tool_call", "name": "computer", "id": "call_1"},
    {"type": "server_tool_result", "tool_call_id": "call_1", "output": "result"},
]
list(_consolidate_calls(items))
# UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value

Review notes

The fix is intentionally minimal: unrecognized tools pass through unchanged rather than attempting a best-effort collapse, since we don't know the target schema for unknown tool types.

AI Disclosure

This bug was identified through code review with AI assistance.

Changed files

  • libs/partners/openai/langchain_openai/chat_models/_compat.py (modified, +5/-2)
  • libs/partners/openai/tests/unit_tests/chat_models/test_base.py (modified, +79/-0)

Code Example

from langchain_openai.chat_models._compat import _consolidate_calls

items = [
    {"type": "server_tool_call", "name": "computer", "id": "call_1"},
    {"type": "server_tool_result", "tool_call_id": "call_1", "output": "result"},
]
list(_consolidate_calls(items))
# UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value

---

UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value
RAW_BUFFERClick to expand / collapse

Package

  • langchain-openai

Reproduction Steps / Example Code (Python)

from langchain_openai.chat_models._compat import _consolidate_calls

items = [
    {"type": "server_tool_call", "name": "computer", "id": "call_1"},
    {"type": "server_tool_result", "tool_call_id": "call_1", "output": "result"},
]
list(_consolidate_calls(items))
# UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value

Error Message and Stack Trace

UnboundLocalError: cannot access local variable 'collapsed' where it is not associated with a value

Description

_consolidate_calls in _compat.py matches pairs of server_tool_call + server_tool_result items and collapses them into the Responses API format. It handles web_search, file_search, code_interpreter, remote_mcp, and mcp_list_tools by name, but if the tool name doesn't match any of these (e.g. computer, image_generation, or any future server tool), collapsed is never assigned and yield collapsed raises UnboundLocalError.

Also, line 314 uses if instead of elif for file_search, which means for every web_search call, the code unnecessarily evaluates the file_search condition and the entire elif chain that follows.

Fix

  1. Add a fallback branch for unrecognized tool names that emits both items unchanged (matching the existing "not a matching pair" behavior)
  2. Change if current.get("name") == "file_search": to elif for consistency with the rest of the chain

System Info

langchain-openai 0.3.22, Python 3.13

extent analysis

Fix Plan

To resolve the issue, we need to modify the _consolidate_calls function in _compat.py. Here are the steps:

  • Add a fallback branch for unrecognized tool names.
  • Change the if statement for file_search to elif for consistency.

Code Changes

from langchain_openai.chat_models._compat import _consolidate_calls

def _consolidate_calls(items):
    # ... existing code ...
    for current, next_item in zip(items, items[1:] + [None]):
        if next_item is not None and current.get("type") == "server_tool_call" and next_item.get("type") == "server_tool_result" and current.get("id") == next_item.get("tool_call_id"):
            if current.get("name") == "web_search":
                # ... existing code ...
            elif current.get("name") == "file_search":
                # ... existing code ...
            # ... existing elif chain ...
            else:
                # Fallback branch for unrecognized tool names
                yield current
                yield next_item
        else:
            yield current

Verification

To verify the fix, run the reproduction code:

items = [
    {"type": "server_tool_call", "name": "computer", "id": "call_1"},
    {"type": "server_tool_result", "tool_call_id": "call_1", "output": "result"},
]
list(_consolidate_calls(items))

This should no longer raise an UnboundLocalError.

Extra Tips

Make sure to test the function with different tool names and scenarios to ensure the fallback branch works as expected. Additionally, consider adding a log statement or warning for unrecognized tool names to facilitate debugging and maintenance.

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