Skip to content

Responses API: undocumented reasoning+message pairing constraint breaks multi-turn conversations #1791

Closed

Description

@achandmsft

Confirm this is a Node library issue and not an underlying OpenAI API issue

  • This is an issue with the Node library

Describe the bug

Reasoning+message items must appear as consecutive pairs in input, but nothing documents this. Common multi-turn patterns silently produce 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.

The most common failure: filtering response.output to keep only messages (dropping reasoning) → 400: Item 'msg_...' of type 'message' was provided without its required preceding item of type 'reasoning'.

Tested in JS, Python, Go, Java, .NET — identical results across all 5 SDKs. This is an API-level constraint, not SDK-specific. 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), so B passes on those runs since there's no message to orphan. Codex with reasoning=high reliably returns both items, making it a deterministic repro.

Workaround: previous_response_id. For manual history, always pass reasoning+message pairs together.

Related:

To Reproduce

import OpenAI from "openai";

const client = new OpenAI();
const conversation: any[] = [];

for (const msg of ["Write a Python prime checker.", "Add type hints.", "Add docstrings."]) {
    conversation.push({ role: "user", content: msg });
    const response = await 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 (const item of response.output) {
        if (item.type === "message") {
            conversation.push(item);  // orphan message → 400 on next turn
        }
    }
}
// Turn 2 → 400: Item 'msg_...' was provided without its required preceding item

Reproduced on o4-mini and gpt-5.3-codex.

OS

Windows 11, also reproduced on Linux

Node version

Node v24.x

Library version

openai v6.32.0

Activity

  1. changed the title [-]Responses API: multi-turn conversations 400 on turn 2 when passing response.output back as input[/-] [+]Responses API: undocumented reasoning + message pairing constraint breaks multi-turn conversations[/+] on Mar 25, 2026
  2. changed the title [-]Responses API: undocumented reasoning + message pairing constraint breaks multi-turn conversations[/-] [+]Responses API: undocumented reasoning+message pairing constraint breaks multi-turn conversations[/+] on Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions