langchain - ✅(Solved) Fix langchain-openai: `_construct_responses_api_input` omits `type: "message"` on user/system/developer items, breaking OpenAI-compatible endpoints [1 pull requests, 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#35689Fetched 2026-04-08 00:25:09
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
closed ×1cross-referenced ×1labeled ×1referenced ×1

_construct_responses_api_input() in libs/partners/openai/langchain_openai/chat_models/base.py builds Responses API input items without explicitly setting "type": "message" on user, system, and developer message dicts. OpenAI's native endpoint silently infers the type, but other OpenAI-compatible endpoints (e.g. Azure AI Foundry) enforce the schema strictly and reject the request with a 400 Bad Request.

Error Message

BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: ''. Supported values are: 
'apply_patch_call', 'apply_patch_call_output', 'code_interpreter_call', 'compaction', 'computer_call', 
'computer_call_output', 'custom_tool_call', 'custom_tool_call_output', 'file_search_call', 'function_call', 
'function_call_output', 'image_generation_call', 'item_reference', 'local_shell_call', 'local_shell_call_output', 
'mcp_approval_request', 'mcp_approval_response', 'mcp_call', 'mcp_list_tools', 'message', 'reasoning', 
'shell_call', 'shell_call_output', and 'web_search_call'.",
'type': 'invalid_request_error', 'param': 'input[1]', 'code': 'invalid_value'}}

The server sees an empty/missing type on input[1] and rejects it because it does not default to "message".

Root Cause

In _construct_responses_api_input(), the user/system/developer code paths append the message dict without a type field:

elif msg["role"] in ("user", "system", "developer"):
    if isinstance(msg["content"], list):
        ...
        if msg["content"]:
            input_.append(msg)    # ← no "type": "message"
    else:
        input_.append(msg)        # ← no "type": "message"
else:
    input_.append(msg)            # ← no "type": "message"

The OpenAI Python SDK's EasyInputMessageParam TypedDict already defines type: Literal["message"] as an (optional) field — setting it explicitly is spec-conforming and a no-op for OpenAI's own endpoint.

Fix Action

Fix / Workaround

BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: ''. Supported values are: 
'apply_patch_call', 'apply_patch_call_output', 'code_interpreter_call', 'compaction', 'computer_call', 
'computer_call_output', 'custom_tool_call', 'custom_tool_call_output', 'file_search_call', 'function_call', 
'function_call_output', 'image_generation_call', 'item_reference', 'local_shell_call', 'local_shell_call_output', 
'mcp_approval_request', 'mcp_approval_response', 'mcp_call', 'mcp_list_tools', 'message', 'reasoning', 
'shell_call', 'shell_call_output', and 'web_search_call'.",
'type': 'invalid_request_error', 'param': 'input[1]', 'code': 'invalid_value'}}

PR fix notes

PR #35702: openai: add explicit type: "message" to Responses API input items

Description (problem / solution / changelog)

Description

_construct_responses_api_input() builds EasyInputMessageParam-style dicts for user, system, and developer messages without the "type" field. OpenAI's native endpoint silently infers "message", but other OpenAI-compatible endpoints (e.g. Azure AI Foundry) enforce the schema strictly and return a 400 Bad Request.

Error

BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: ''. Supported values are: 
'apply_patch_call', ..., 'message', ..., and 'web_search_call'.",
'type': 'invalid_request_error', 'param': 'input[1]', 'code': 'invalid_value'}}

Fix

Sets msg["type"] = "message" explicitly on every user/system/developer input item (and the else fallthrough) before appending to the input_ list.

This is:

  • Spec-conformingEasyInputMessageParam already defines type: Literal["message"]
  • Backward-compatible — a no-op for OpenAI's endpoint which already infers it
  • Required for Azure AI Foundry and potentially other strict OpenAI-compatible services

Fixes #35689

Changed files

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

Code Example

from langchain_openai import ChatOpenAI

# Using any OpenAI-compatible endpoint that strictly enforces the Responses API schema
model = ChatOpenAI(
    base_url="https://<resource>.services.ai.azure.com/openai/v1",
    api_key="...",
    model="gpt-4o",
)

model.invoke([
    {"role": "developer", "content": "Translate from English into Italian"},
    {"role": "user", "content": "hi!"},
])

---

BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: ''. Supported values are: 
'apply_patch_call', 'apply_patch_call_output', 'code_interpreter_call', 'compaction', 'computer_call', 
'computer_call_output', 'custom_tool_call', 'custom_tool_call_output', 'file_search_call', 'function_call', 
'function_call_output', 'image_generation_call', 'item_reference', 'local_shell_call', 'local_shell_call_output', 
'mcp_approval_request', 'mcp_approval_response', 'mcp_call', 'mcp_list_tools', 'message', 'reasoning', 
'shell_call', 'shell_call_output', and 'web_search_call'.",
'type': 'invalid_request_error', 'param': 'input[1]', 'code': 'invalid_value'}}

---

elif msg["role"] in ("user", "system", "developer"):
    if isinstance(msg["content"], list):
        ...
        if msg["content"]:
            input_.append(msg)    # ← no "type": "message"
    else:
        input_.append(msg)        # ← no "type": "message"
else:
    input_.append(msg)            # ← no "type": "message"
RAW_BUFFERClick to expand / collapse

Description

_construct_responses_api_input() in libs/partners/openai/langchain_openai/chat_models/base.py builds Responses API input items without explicitly setting "type": "message" on user, system, and developer message dicts. OpenAI's native endpoint silently infers the type, but other OpenAI-compatible endpoints (e.g. Azure AI Foundry) enforce the schema strictly and reject the request with a 400 Bad Request.

Reproduction

from langchain_openai import ChatOpenAI

# Using any OpenAI-compatible endpoint that strictly enforces the Responses API schema
model = ChatOpenAI(
    base_url="https://<resource>.services.ai.azure.com/openai/v1",
    api_key="...",
    model="gpt-4o",
)

model.invoke([
    {"role": "developer", "content": "Translate from English into Italian"},
    {"role": "user", "content": "hi!"},
])

Error

BadRequestError: Error code: 400 - {'error': {'message': "Invalid value: ''. Supported values are: 
'apply_patch_call', 'apply_patch_call_output', 'code_interpreter_call', 'compaction', 'computer_call', 
'computer_call_output', 'custom_tool_call', 'custom_tool_call_output', 'file_search_call', 'function_call', 
'function_call_output', 'image_generation_call', 'item_reference', 'local_shell_call', 'local_shell_call_output', 
'mcp_approval_request', 'mcp_approval_response', 'mcp_call', 'mcp_list_tools', 'message', 'reasoning', 
'shell_call', 'shell_call_output', and 'web_search_call'.",
'type': 'invalid_request_error', 'param': 'input[1]', 'code': 'invalid_value'}}

The server sees an empty/missing type on input[1] and rejects it because it does not default to "message".

Root cause

In _construct_responses_api_input(), the user/system/developer code paths append the message dict without a type field:

elif msg["role"] in ("user", "system", "developer"):
    if isinstance(msg["content"], list):
        ...
        if msg["content"]:
            input_.append(msg)    # ← no "type": "message"
    else:
        input_.append(msg)        # ← no "type": "message"
else:
    input_.append(msg)            # ← no "type": "message"

The OpenAI Python SDK's EasyInputMessageParam TypedDict already defines type: Literal["message"] as an (optional) field — setting it explicitly is spec-conforming and a no-op for OpenAI's own endpoint.

Expected behavior

All message-role items in the Responses API input array should include "type": "message" so the output is valid for any OpenAI-compatible endpoint.

Suggested fix

Add msg["type"] = "message" before each input_.append(msg) call for user/system/developer messages (and the else fallthrough) in _construct_responses_api_input().

extent analysis

Fix: Explicitly Set "type" Field in Responses API Input

Step-by-Step Solution Plan

  1. Update _construct_responses_api_input() in libs/partners/openai/langchain_openai/chat_models/base.py to set the "type" field for user, system, and developer messages:

elif msg["role"] in ("user", "system", "developer"): if isinstance(msg["content"], list): ... if msg["content"]: msg["type"] = "message" # Add this line input_.append(msg) else: msg["type"] = "message" # Add this line input_.append(msg) else: msg["type"] = "message" # Add this line input_.append(msg)

2. **Commit and push changes** to the updated file.

### Verification

1. **Reproduce the issue** with the updated code to ensure the fix works.
2. **Verify the API request** is sent with the correct schema, including the `"type"` field for user, system, and developer messages.
3. **Check the API response** to ensure it is successful and returns the expected output.

### Extra Tips

* Make sure to test the fix with different OpenAI-compatible endpoints to ensure it works as expected.
* Consider adding a test case to the code to verify the fix works correctly.
* If you're using a CI/CD pipeline, update the pipeline to include a test for this fix.

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…

FAQ

Expected behavior

All message-role items in the Responses API input array should include "type": "message" so the output is valid for any OpenAI-compatible endpoint.

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 langchain-openai: `_construct_responses_api_input` omits `type: "message"` on user/system/developer items, breaking OpenAI-compatible endpoints [1 pull requests, 1 participants]