-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Confirm this is an issue with the Python library and not an underlying OpenAI API
- This is an issue with the Python library
Describe the bug
Reasoning+message items must appear as consecutive pairs in input, but nothing documents this. The most common pattern — filtering response.output to keep only messages — silently produces orphaned items → 400 on the next turn.
This broke OpenClaw (64.9k forks) on gpt-5.3-codex. They had to add downgradeOpenAIReasoningBlocks() to strip orphan reasoning items.
400: Item 'msg_...' of type 'message' was provided without its required preceding item of type 'reasoning'
Tested in Python, JS, Go, Java, .NET — identical results across all 5 SDKs. This is an API-level constraint, not SDK-specific. Confirmed via curl (see gist). The SDK types don't prevent building input arrays that violate it.
| Model | A (all items) | B (msgs only) |
|---|---|---|
| gpt-5.3-codex (reasoning=high) | PASS | FAIL |
| o4-mini | PASS | FAIL* |
* Nondeterministic — o4-mini sometimes returns reasoning-only output (no message to orphan). Codex with reasoning=high reliably returns both items.
Workaround: previous_response_id. For manual history, always pass reasoning+message pairs together.
Note: there's a separate Python-specific bug where model_dump() fabricates null fields (status: None, encrypted_content: None) → 400: Unknown parameter. That's tracked in #3008 and is independent of this pairing constraint.
Related:
- Responses API: undocumented reasoning+message pairing constraint breaks multi-turn conversations across all SDKs openai-openapi#536 (spec root cause)
- Responses API: undocumented reasoning+message pairing constraint breaks multi-turn conversations openai-node#1791 (same bug, Node SDK)
- openai/openai-dotnet#TBD (same bug, .NET SDK)
- openai/openai-go#TBD (same bug, Go SDK)
- openai/openai-java#TBD (same bug, Java SDK)
- openclaw/openclaw#49167 (64.9k forks, production breakage)
- Error "Item ‘rs_ABCD’ of type ‘reasoning’ was provided without its required..." when using CodeInterpreter #2561 (open since Aug 2025)
- GPT-5 + tool calls: Error code: 400 - Item 'rs_...' of type 'reasoning' was provided without its required following item. openai-agents-python#1660 (Agents SDK)
To Reproduce
from openai import OpenAI, APIError
client = OpenAI()
conversation = []
for msg in ["Write a Python prime checker.", "Add type hints.", "Add docstrings."]:
conversation.append({"role": "user", "content": msg})
try:
response = client.responses.create(
model="gpt-5.3-codex",
input=conversation,
max_output_tokens=300,
reasoning={"effort": "high"},
)
# Common pattern: keep only messages, discard reasoning
for item in response.output:
if item.type == "message":
conversation.append(item.model_dump(exclude_none=True))
except APIError as e:
print(f"ERROR: {e.status_code} - {e.message}")
break
# Turn 2 → 400: Item 'msg_...' was provided without its required preceding itemReproduced on o4-mini and gpt-5.3-codex. Full cross-language repro (Python, JS, .NET, curl): https://gist.github.com/achandmsft/57886350885cec3af8ef3f456ed529cf
Code snippets
OS
Windows 11, also reproduced on Linux
Python version
Python v3.13
Library version
openai v2.29.0