langchain - ✅(Solved) Fix Agent with structured output fails when OpenAI response has phased response with 'commentary' and 'final_answer' [1 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#36290Fetched 2026-04-08 01:36:05
View on GitHub
Comments
7
Participants
5
Timeline
19
Reactions
0
Timeline (top)
commented ×7labeled ×4mentioned ×3subscribed ×3

The repro doesn't include an actual model call because it's intermittent (the model doesn't always respond with those phases). You can see the reference to 'phases' here in the OpenAI Python repo, if that helps.

Error Message

C:\Users\david\dev\trovono.venv\Lib\site-packages\langchain_core_api\deprecation.py:25: UserWarning: Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater. from pydantic.v1.fields import FieldInfo as FieldInfoV1 Traceback (most recent call last): File "C:\Users\david\dev\trovono.venv\Lib\site-packages\langchain\agents\structured_output.py", line 410, in parse data = json.loads(raw_text) File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json_init_.py", line 346, in loads return _default_decoder.decode(s) ~~~~~~~~~~~~~~~~~~~~~~~^^^ File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json\decoder.py", line 348, in decode raise JSONDecodeError("Extra data", s, end) json.decoder.JSONDecodeError: Extra data: line 1 column 28 (char 27)

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "C:\Users\david\dev\trovono\repro.py", line 23, in <module> ).parse(message) ~~~~~^^^^^^^^^ File "C:\Users\david\dev\trovono.venv\Lib\site-packages\langchain\agents\structured_output.py", line 417, in parse raise ValueError(msg) from e ValueError: Native structured output expected valid JSON for MyModel, but parsing failed: Extra data: line 1 column 28 (char 27).

Root Cause

The repro doesn't include an actual model call because it's intermittent (the model doesn't always respond with those phases). You can see the reference to 'phases' here in the OpenAI Python repo, if that helps.

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.

System Information

OS: Windows OS Version: 10.0.26200 Python Version: 3.14.0 (main, Nov 19 2025, 22:43:52) [MSC v.1944 64 bit (AMD64)] Package Information


langchain_core: 1.2.22 langchain: 1.2.13 langsmith: 0.7.22 langchain_google_genai: 4.2.1 langchain_openai: 1.1.12 langgraph_sdk: 0.3.4 Optional packages not installed


deepagents deepagents-cli Other Dependencies


filetype: 1.2.0 google-genai: 1.68.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.1.3 openai: 2.30.0 openai-agents: 0.11.1 orjson: 3.11.7 packaging: 26.0 pydantic: 2.12.5 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 rich: 14.3.2 tenacity: 9.1.4 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.14.0 websockets: 15.0.1 xxhash: 3.6.0 zstandard: 0.25.0

PR fix notes

PR #36307: fix: handle phased multi-text output in ProviderStrategyBinding parsing

Description (problem / solution / changelog)

Fixes #36290

Description

Background

With OpenAI’s phased responses, an AIMessage may contain multiple text blocks, such as commentary and final_answer.

The current implementation of _extract_text_content_from_message() concatenates all text blocks into a single string. When multiple blocks contain JSON, this can produce invalid JSON and cause parsing to fail.

Problem

For example:

[
    {"type": "text", "phase": "commentary", "text": '{"some_field": "some text"}'},
    {"type": "text", "phase": "final_answer", "text": '{"some_field": "some other text"}'},
]

Concatenating these results in:

{"some_field": "some text"}{"some_field": "some other text"}

which raises a JSONDecodeError: Extra data during json.loads().

Solution

This PR updates _extract_text_content_from_message() to:

  • Preserve existing behavior when content is a string
  • Iterate through list-based content as before
  • Return immediately when encountering a text block with phase == "final_answer"
  • Fall back to the original concatenation logic when no final_answer block is present

This ensures compatibility with phased multi-text outputs while minimizing changes to existing behavior.

Tests

Added/updated tests to cover:

  • Standard single-string parsing (unchanged behavior)
  • Multi-text content with a final_answer block (correctly selects final output)
  • Existing list-based content parsing (backward compatibility)

Backward Compatibility

This change is fully backward compatible:

  • No impact on single-string inputs
  • Existing list-based parsing behavior is preserved
  • Only improves handling of phased multi-text responses

Changed files

  • libs/langchain_v1/langchain/agents/structured_output.py (modified, +2/-0)
  • libs/langchain_v1/tests/unit_tests/agents/test_responses.py (modified, +17/-0)

Code Example

from langchain.agents.structured_output import ProviderStrategyBinding
from langchain_core.messages import AIMessage
from pydantic import BaseModel


class MyModel(BaseModel):
    some_field: str


# OpenAI sometimes responds with MULTIPLE items of type 'text'
message = AIMessage(
    content=[
        dict(type="text", phase="commentary", text='{"some_field": "some text"}'),
        dict(type="text", phase="final_answer", text='{"some_field": "some other text"}'),
    ]
)

ProviderStrategyBinding(
    schema=MyModel,
    schema_kind="pydantic",
).parse(message)

---

C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain_core\_api\deprecation.py:25: UserWarning: Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater.
  from pydantic.v1.fields import FieldInfo as FieldInfoV1
Traceback (most recent call last):
  File "C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain\agents\structured_output.py", line 410, in parse
    data = json.loads(raw_text)
  File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json\decoder.py", line 348, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 28 (char 27)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\david\dev\trovono\repro.py", line 23, in <module>
    ).parse(message)
      ~~~~~^^^^^^^^^
  File "C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain\agents\structured_output.py", line 417, in parse
    raise ValueError(msg) from e
ValueError: Native structured output expected valid JSON for MyModel, but parsing failed: Extra data: line 1 column 28 (char 27).
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. 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

No response

Reproduction Steps / Example Code (Python)

from langchain.agents.structured_output import ProviderStrategyBinding
from langchain_core.messages import AIMessage
from pydantic import BaseModel


class MyModel(BaseModel):
    some_field: str


# OpenAI sometimes responds with MULTIPLE items of type 'text'
message = AIMessage(
    content=[
        dict(type="text", phase="commentary", text='{"some_field": "some text"}'),
        dict(type="text", phase="final_answer", text='{"some_field": "some other text"}'),
    ]
)

ProviderStrategyBinding(
    schema=MyModel,
    schema_kind="pydantic",
).parse(message)

Error Message and Stack Trace (if applicable)

C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain_core\_api\deprecation.py:25: UserWarning: Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater.
  from pydantic.v1.fields import FieldInfo as FieldInfoV1
Traceback (most recent call last):
  File "C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain\agents\structured_output.py", line 410, in parse
    data = json.loads(raw_text)
  File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "C:\Users\david\AppData\Roaming\uv\python\cpython-3.14.0-windows-x86_64-none\Lib\json\decoder.py", line 348, in decode
    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 28 (char 27)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\david\dev\trovono\repro.py", line 23, in <module>
    ).parse(message)
      ~~~~~^^^^^^^^^
  File "C:\Users\david\dev\trovono\.venv\Lib\site-packages\langchain\agents\structured_output.py", line 417, in parse
    raise ValueError(msg) from e
ValueError: Native structured output expected valid JSON for MyModel, but parsing failed: Extra data: line 1 column 28 (char 27).

Description

The repro doesn't include an actual model call because it's intermittent (the model doesn't always respond with those phases). You can see the reference to 'phases' here in the OpenAI Python repo, if that helps.

System Info

System Information

OS: Windows OS Version: 10.0.26200 Python Version: 3.14.0 (main, Nov 19 2025, 22:43:52) [MSC v.1944 64 bit (AMD64)] Package Information


langchain_core: 1.2.22 langchain: 1.2.13 langsmith: 0.7.22 langchain_google_genai: 4.2.1 langchain_openai: 1.1.12 langgraph_sdk: 0.3.4 Optional packages not installed


deepagents deepagents-cli Other Dependencies


filetype: 1.2.0 google-genai: 1.68.0 httpx: 0.28.1 jsonpatch: 1.33 langgraph: 1.1.3 openai: 2.30.0 openai-agents: 0.11.1 orjson: 3.11.7 packaging: 26.0 pydantic: 2.12.5 pyyaml: 6.0.3 requests: 2.32.5 requests-toolbelt: 1.0.0 rich: 14.3.2 tenacity: 9.1.4 tiktoken: 0.12.0 typing-extensions: 4.15.0 uuid-utils: 0.14.0 websockets: 15.0.1 xxhash: 3.6.0 zstandard: 0.25.0

extent analysis

Fix Plan

To fix the issue, we need to modify the parse method in ProviderStrategyBinding to handle the case where the OpenAI model responds with multiple items of type 'text'. We can achieve this by iterating over the content of the AIMessage and parsing each item separately.

Here are the steps to fix the issue:

  • Modify the parse method to iterate over the content of the AIMessage.
  • For each item, check if it's a dictionary with a 'type' key equal to 'text' and a 'text' key that contains a valid JSON string.
  • If the item is a valid JSON string, parse it into a Python object using the json.loads method.
  • If the parsed object conforms to the expected schema (in this case, MyModel), return it as the result of the parse method.

Here's an example of how the modified parse method could look:

import json
from langchain.agents.structured_output import ProviderStrategyBinding
from langchain_core.messages import AIMessage
from pydantic import BaseModel

class MyModel(BaseModel):
    some_field: str

class CustomProviderStrategyBinding(ProviderStrategyBinding):
    def parse(self, message: AIMessage):
        for item in message.content:
            if item.get('type') == 'text' and item.get('text'):
                try:
                    data = json.loads(item['text'])
                    if isinstance(data, dict) and 'some_field' in data:
                        return MyModel(**data)
                except json.JSONDecodeError:
                    pass
        raise ValueError("Native structured output expected valid JSON for MyModel, but parsing failed")

# Usage
message = AIMessage(
    content=[
        dict(type="text", phase="commentary", text='{"some_field": "some text"}'),
        dict(type="text", phase="final_answer", text='{"some_field": "some other text"}'),
    ]
)

binding = CustomProviderStrategyBinding(
    schema=MyModel,
    schema_kind="pydantic",
)
result = binding.parse(message)
print(result)

Verification

To verify that the fix worked, you can run the modified code with the provided example AIMessage and check that the parse method returns the expected result. You can also test the code with different inputs to ensure that it handles various scenarios correctly.

Extra Tips

  • Make sure to handle any potential exceptions that may occur during the parsing process, such as JSONDecodeError.
  • Consider adding additional logging or debugging statements to help diagnose any issues that may arise during the parsing process.
  • If you're using a custom schema, ensure that it's correctly defined and that the parse method is able to handle any nuances of the schema.

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