Responses API: undocumented reasoning+message pairing constraint breaks multi-turn conversations
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
PairingConstraintRepro に示されている Responses API のフローから始め、特に ResponseInputUnionParam、ResponseCreateParams、response.output()、previousResponseId() を確認してください。記載されたモデルで 2 ターン目の失敗を再現し、対応がこの SDK に属するのか API に属するのかを判断してください。明確に特定された、テスト可能な担当範囲と動作変更が得られれば完了です。
索引モデルが issue の本文から書いたものです。
説明
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 Java, JS, Python, Go, .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: previousResponseId(). For manual history, always pass reasoning+message pairs together.
Related:
- openai/openai-openapi#536 (spec root cause)
- openai/openai-node#1791 (same bug, Node SDK)
- openai/openai-python#TBD (same bug, Python SDK)
- openai/openai-dotnet#TBD (same bug, .NET SDK)
- openai/openai-go#TBD (same bug, Go SDK)
- openclaw/openclaw#49167 (64.9k forks, production breakage)
To Reproduce
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.*;
import java.util.ArrayList;
import java.util.List;
public class PairingConstraintRepro {
public static void main(String[] args) {
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
String[] prompts = {"Write a Python prime checker.", "Add type hints.", "Add docstrings."};
List<ResponseInputUnionParam> conversation = new ArrayList<>();
for (String msg : prompts) {
System.out.println("\n> " + msg);
conversation.add(ResponseInputUnionParam.ofEasyInputMessage(
EasyInputMessageParam.builder()
.role(EasyInputMessageParam.Role.USER)
.content(msg)
.build()));
try {
Response response = client.responses().create(
ResponseCreateParams.builder()
.model("gpt-5.3-codex")
.input(ResponseCreateParams.Input.ofResponseInputs(conversation))
.maxOutputTokens(300)
.reasoning(Reasoning.builder().effort(Reasoning.Effort.HIGH).build())
.build());
// Common pattern: keep only messages, discard reasoning
for (ResponseOutputItem item : response.output()) {
if (item.isMessage()) {
// Convert output message to input — orphan message → 400
conversation.add(ResponseInputUnionParam.ofResponseInputItem(
ResponseInputItemParam.builder()
.id(item.asMessage().id())
.type(ResponseInputItemParam.Type.MESSAGE)
.build()));
}
}
} catch (Exception e) {
System.out.println(" ERROR: " + e.getMessage().substring(0, Math.min(120, e.getMessage().length())));
break;
}
}
// Turn 2 → 400: Item 'msg_...' was provided without its required preceding item
}
}
Note: the Java SDK's distinct input/output wrapper types make the conversion verbose, but the pairing constraint failure is the same regardless.
Reproduced on o4-mini and gpt-5.3-codex. Full cross-language repro (JS, Python, .NET, curl): https://gist.github.com/achandmsft/57886350885cec3af8ef3f456ed529cf
OS
Windows 11, also reproduced on Linux
Java version
Java 21
Library version
openai-java v4.29.0
- 主要言語
- Kotlin
- スター
- 1.5k
- フォーク
- 266
- 平均マージ
- 10時間 11分
- マージ済み PR(30日)
- 141
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
openai/openai-java のほかの issue
-
HttpRequest.url() logs spaces in path segments as literal plus signs対応中かも @sylvesterkaczmarek が 54 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
openai/openai-java#886 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
Make diarized transcription duration and task optional対応中かも @wskr00 が 85 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
openai/openai-java#802 · コメント 2 件 · リアクション 3 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 半日 初心者へのやさしさ 42/100
openai/openai-java#1160 ·
メンテナーはふだん 1 日以内に返信
-
AsyncStreamResponse can hang when the subscriber executor rejects work対応中かも @sylvesterkaczmarek が 38 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 74/100
openai/openai-java#973 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
openai/openai-java#956 ·
メンテナーはふだん 1 日以内に返信
openai/openai-java の issue をすべて見る
似ている issue
-
M1 manhwa listオープンBug Domain changed
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
keiyoushi/extensions-source#19882 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 3 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
lugassawan/swe-workbench#799 ·
メンテナーはふだん 1 日以内に返信
-
Default book icon displayed while loading対応中かも @Bhaskar-Guthula-137 が今日担当しました。 オープンbug good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
kiwix/kiwix-android#5194 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
d4rken-org/butler#300 ·
メンテナーはふだん 1 日以内に返信