`store: false` breaks multi-turn computer-use

Summary

When using the Responses API with store: false and the computer tool, multi-turn conversations fail on the second turn. The API returns output items (reasoning, message, computer_call) with server-generated id fields. When those items are sent back as conversation history in the next request, the API tries to resolve those IDs against server-side storage — which doesn’t exist because store: false was set.

Two failure modes

1. 404 — reasoning item present

If the response’s output array is passed back verbatim (including the reasoning item with its rs_ prefixed ID), the API returns 404 Not Found.

2. 500 — reasoning item omitted, other IDs remain

The 404 error message suggests removing the unresolvable item. If you strip the reasoning item (which has an empty summary and no useful content anyway), the request gets past the 404 — but then the API returns 500 Internal Server Error.

Expected behavior

The API should accept verbatim playback of the output items it returned, or the docs should describe what transformations are needed for store: false multi-turn.

Reproduction

This attached script exercises both cases with a single minimal request body.

set -euo pipefail
set -a; source .env; set +a

: "${OPENAI_API_KEY:?Set OPENAI_API_KEY}"

# 1x1 red PNG as a minimal valid screenshot
TINY_PNG="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg=="

COMMON=(-s -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json")

REASONING_ITEM='{
      "id": "rs_083ff13b99ce487d0169ab5455d3c4819a9e2efe7f45534b3c",
      "type": "reasoning",
      "summary": []
    },'

send_request() {
  local reasoning_item="$1"
  curl "${COMMON[@]}" https://api.openai.com/v1/responses -d @- <<EOF
{
  "instructions": "You are controlling a browser-based kanban app through the built-in computer tool.",
  "input": [
    {
      "content": [
        { "text": "what's on the desktop", "type": "input_text" }
      ],
      "role": "user"
    },
    ${reasoning_item}
    {
      "id": "msg_083ff13b99ce487d0169ab545999d0819aa3edf6123fdab1f9",
      "type": "message",
      "status": "completed",
      "content": [
        { "type": "output_text", "text": "" }
      ],
      "role": "assistant"
    },
    {
      "id": "cu_083ff13b99ce487d0169ab5459c7e4819a9f0c36ae97db6e86",
      "type": "computer_call",
      "status": "completed",
      "actions": [{ "type": "screenshot" }],
      "call_id": "call_2dugsE4CytbpbsqMriR5KV5C"
    },
    {
      "type": "computer_call_output",
      "call_id": "call_2dugsE4CytbpbsqMriR5KV5C",
      "output": {
        "type": "computer_screenshot",
        "image_url": "${TINY_PNG}"
      }
    }
  ],
  "model": "gpt-5.4",
  "reasoning": { "effort": "low" },
  "store": false,
  "tools": [{ "type": "computer" }]
}
EOF
  echo ""
}

echo "--- Test 1: with reasoning item → expect 404 ---"
send_request "$REASONING_ITEM"

echo "--- Test 2: reasoning removed → expect 500 ---"
send_request ""

Prerequisites

  • OPENAI_API_KEY set in the environment (or in a .env file in the working directory)
  • curl and bash

Running

The script runs two requests and prints the API error response for each.

Environment

  • Model: gpt-5.4
  • Endpoint: POST /v1/responses
  • Tool: computer
  • store: false
2 Likes

Thanks for reporting this. I took a closer look and was able to reproduce part of what you’re seeing, but not all of it.

What still reproduces is the 404 path. Replaying a plain reasoning item under store: false still fails with 404. From what I observed, that happens because the returned reasoning item includes an rs_... ID, and on the next turn the API tries to resolve that ID server-side even though nothing was stored.

What I could not reproduce anymore is the older follow-up behavior where removing the reasoning item led to a 500. In current testing, that no longer happened. I saw the same result both with a static payload and with fresh live two-turn runs using the built-in computer tool.

So the current picture appears to be:

  • Replaying a plain reasoning item under store: false still fails with 404.
  • Removing that plain reasoning item works.
  • Replaying the reasoning item also works if the first turn requested include: ["reasoning.encrypted_content"].

I also validated those last two paths in repeated live runs before suggesting them here, and both worked consistently.

So the practical unblockers are:

  • If you can change the first request, add include: ["reasoning.encrypted_content"] on the initial call, then replay the returned reasoning item verbatim on the next turn.
  • If you cannot change the first request, omit the plain reasoning item on replay and continue with the computer_call and computer_call_output items.

So in short, this still looks like a real issue for plain reasoning-item replay under store: false, but the 500 path no longer appears reproducible, and the two workarounds above are currently working in live tests.

You need to request encrypted content in “include” and sent back encrypted content in the reasoning item for self-management.

Your code example is missing that part.

Then, against common sense, the ID is not something that you can strip, you have to send it back also, but you can also fabricate a lookalike to demonstrate that the ID doesn’t rely on prior state held on the server.

The summary with strings is also a required key.

Hey everyone, Can someone confirm if this is still or the workaround from @vb helps?

1 Like