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:9000 → ws://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):
- Open connection A. Send
response.create with "store": false and input "Reply with the single word: cherry.". Capture the returned response.id.
- Close connection A.
- 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.".
- 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.
Summary
On the WebSocket Responses endpoint, a
response.createsent withstore: falsestill causes the server to persist conversation state: the returnedprevious_response_idis 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 subsequentprevious_response_idlookup 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
storeparameter for/v1/responsesis always treated asfalse. Understore: false, response/reasoning items are not persisted, so chaining viaprevious_response_idfails 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 asinputon 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.createwithstore: falsereturns aresponse.id. Sending that id asprevious_response_idon 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 despitestore: false.Environment
/v1/responses), reached viakubectl port-forward svc/agentic-api -n agentic-api 19000:9000→ws://localhost:19000/v1/responses/models/models/GLM-5.2-FP8Reproduction
Each
response.createenvelope 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": falseand/or"previous_response_id": "<id>"where noted). Read events untilresponse.completed.Case — cross-connection chaining with
store: false(the bug):response.createwith"store": falseand input"Reply with the single word: cherry.". Capture the returnedresponse.id.response.createwith"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.".cherry— thestore: falsestate was resolved across a new connection.Expected: the lookup should not resolve (error or no recall), since
store: falsemeans nothing is persisted server-side.Negative control (confirms the id is what carries state, not model guessing):
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 onprevious_response_id.Actual results captured
storeprevious_response_idsent?trueapple)truebanana)falsecherry) ← bugImpact
Clients relying on
store: falsefor 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 documentedstore: falsecontract 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_idfor such responses — matching the OpenAI Responses API contract, where stateless/ZDR clients replay full history viainput.