Skip to content

store: false still persists and resolves previous_response_id across WebSocket connections (breaks ZDR expectation) #238

Description

@jtechapps

Summary

On the WebSocket Responses endpoint, a response.create sent with store: false still causes the server to persist conversation state: the returned previous_response_id is later resolved on a brand-new WebSocket connection. Per the OpenAI Responses API spec, store: false (and the Zero Data Retention mode that forces it) means state is not persisted server-side and a subsequent previous_response_id lookup should not resolve — clients are expected to replay full history themselves. This divergence means data a ZDR client expected to be held only in memory (connection-local) is retained and retrievable across connections.

Expected behavior (per OpenAI spec)

With ZDR enabled at the org level, the store parameter for /v1/responses is always treated as false. Under store: false, response/reasoning items are not persisted, so chaining via previous_response_id fails with an error along the lines of "Items are not persisted when store is set to false. Try again with store set to true, or remove this item from your input." Stateless/ZDR clients must instead pass the full conversation history as input on each turn. See Data controls in the OpenAI platform and Conversation state or create new lane in the same connection.

Observed behavior (agentic-api)

A response.create with store: false returns a response.id. Sending that id as previous_response_id on a separate, freshly opened WebSocket connection resolves the prior context and the model recalls the earlier content — i.e. the state was persisted server-side and is retrievable across connections despite store: false.

Environment

  • Endpoint: vLLM agentic-api WebSocket Responses endpoint (/v1/responses), reached via kubectl port-forward svc/agentic-api -n agentic-api 19000:9000ws://localhost:19000/v1/responses
  • Model: /models/models/GLM-5.2-FP8

Reproduction

Each response.create envelope has the shape:

{
  "type": "response.create",
  "model": "/models/models/GLM-5.2-FP8",
  "input": [{"role": "user", "content": "<text>"}],
  "max_output_tokens": 512,
  "stream_id": "probe"
}

(plus "store": false and/or "previous_response_id": "<id>" where noted). Read events until response.completed.

Case — cross-connection chaining with store: false (the bug):

  1. Open connection A. Send response.create with "store": false and input "Reply with the single word: cherry.". Capture the returned response.id.
  2. Close connection A.
  3. Open a new connection B. Send response.create with "previous_response_id": "<id from step 1>" and input "What single word did I ask you to say in my previous message? Reply with only that word.".
  4. Observed: the model replies cherry — the store: false state was resolved across a new connection.

Expected: the lookup should not resolve (error or no recall), since store: false means nothing is persisted server-side.

Negative control (confirms the id is what carries state, not model guessing):

  • Repeat step 3 on a fresh connection with no previous_response_id. The model correctly does not recall the word (it responds that there is no previous message in the session). This rules out the model inferring the answer, confirming that the cross-connection recall in the bug case is genuine server-side persistence keyed on previous_response_id.

Actual results captured

Scenario store New connection? previous_response_id sent? Result
Baseline (same conn) true no yes RESOLVED (recalled apple)
Cross-connection true yes yes RESOLVED (recalled banana)
Cross-connection false yes yes RESOLVED (recalled cherry) ← bug
Negative control yes no NOT resolved (no recall) ✔

Impact

Clients relying on store: false for Zero Data Retention (state held only in memory / connection-local) get server-side persistence they explicitly opted out of, and that state remains retrievable from other connections holding the response id. This both violates the documented store: false contract and is a data-retention concern for ZDR deployments.

Suggested fix

Under store: false, do not persist response/reasoning items server-side, and reject (or refuse to resolve) previous_response_id for such responses — matching the OpenAI Responses API contract, where stateless/ZDR clients replay full history via input.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions