Bug: Multi-turn tool call sessions fail with 404 for BYOK configurations when store is false but reasoning item IDs are included in subsequent requests
Summary
When using a BYOK (Bring Your Own Key) configuration, the SDK sends multi-turn conversations using the Responses API — including prior reasoning items by ID in the input array — but explicitly sets store: false on each request. Because items are not persisted server-side when store: false, any subsequent turn that references a prior reasoning item ID receives a 404 Invalid Request error, breaking all multi-turn agentic/tool-call flows.
Reproduction
Prerequisites: This requires both a BYOK configuration and wireApi=responses to be set. Without wireApi=responses, the SDK routes through the Completions API and the issue does not occur.
Any multi-turn conversation that involves tool use and reasoning will trigger this. Steps:
- Configure the SDK with
wireApi=responses and a BYOK key.
- Send an initial message to the Responses API with
reasoning.effort set (e.g. "medium"), store: false, and stream: true.
- The model performs a tool call. The response includes a
reasoning item with an rs_ prefixed ID and encrypted_content (included via include: ["reasoning.encrypted_content"]).
- On the next turn, the SDK reconstructs the conversation history, appending the prior reasoning item and function call/output items to
input.
- The API rejects the request with HTTP 404:
{
"error": {
"message": "Item with id 'rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3' not found. Items are not persisted when `store` is set to false. Try again with `store` set to true, or remove this item from your input.",
"type": "invalid_request_error",
"param": "input",
"code": null
}
}
Request Trace (Simplified)
Turn 2 request body (the failing one):
{
"model": "gpt-5.2-chat-latest",
"store": false,
"stream": true,
"include": ["reasoning.encrypted_content"],
"reasoning": { "summary": "auto", "effort": "medium" },
"input": [
{ "role": "user", "content": [...], "type": "message" },
{
"id": "rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3",
"type": "reasoning",
"summary": [{ "text": "...", "type": "summary_text" }]
},
{ "type": "function_call", "id": "fc_call_5K9YT6DAU9wVqpZydr6eb8Rx", ... },
{ "type": "function_call_output", "call_id": "call_5K9YT6DAU9wVqpZydr6eb8Rx", "output": "..." }
]
}
Note: store: false is explicitly set by the SDK in the outgoing request — it is not being forced by the server.
Response: HTTP 404
Root Cause
The copilot cli is explicitly setting store: false on each request (confirmed in the request trace above). The cli then reconstructs multi-turn conversation history incorrectly.
Per the [OpenAI Cookbook on reasoning items](https://cookbook.openai.com/examples/responses_api/reasoning_items), when store: false is used, reasoning items cannot be referenced by ID alone — the server has nothing persisted to resolve them against. The correct stateless pattern requires:
- Request
include: ["reasoning.encrypted_content"] — the cli already does this ✅
- On the next turn, pass the reasoning item back with its
encrypted_content blob populated — the cli is not doing this ❌
Instead, the cli reconstructs the reasoning item in input with only id and summary, omitting encrypted_content. The server cannot resolve the ID (nothing was stored), hence the 404.
The [Azure OpenAI Responses API documentation](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/responses?view=foundry-classic) states this explicitly:
"When using the Responses API in stateless mode by setting store to false, you must still preserve reasoning context across conversation turns. To do this, include encrypted reasoning items in your API requests... add reasoning.encrypted_content to the include parameter... This ensures that the response includes an encrypted version of the reasoning trace, which can be passed along in future requests."
The [OpenAI API Reference for the Responses object](https://platform.openai.com/docs/api-reference/responses) confirms that encrypted_content is the field that must be populated on reasoning items when operating statelessly.
Expected Behavior
When store: false is set and a prior turn produced a reasoning item, the SDK must persist and replay the full reasoning item including the encrypted_content field in the input array on the next turn. The id and summary alone are insufficient for stateless operation.
Concretely, the reasoning item in the Turn 2 input should look like:
{
"id": "rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3",
"type": "reasoning",
"summary": [{ "text": "...", "type": "summary_text" }],
"encrypted_content": "<blob from turn 1 response>"
}
Impact
All multi-turn agentic conversations with reasoning enabled are broken for BYOK configurations. Any BYOK app using the SDK with tool use + reasoning will hit this on the second turn.
Environment
- SDK:
github/copilot-sdk (Python backend via GitHub Copilot SDK)
- API endpoint:
/responses
- Required config:
wireApi=responses + BYOK key
- Model:
gpt-5.2-chat-latest
- Reasoning config:
{ "summary": "auto", "effort": "medium" }
- Repro rate: 100% on any BYOK +
wireApi=responses multi-turn tool call session with reasoning enabled
Suggested Fix
When serializing prior reasoning items into the input array for the next turn, ensure encrypted_content is captured from the prior response and included:
# When building input history from a prior response item of type "reasoning":
if item.type == "reasoning" and item.encrypted_content:
history_item = {
"id": item.id,
"type": "reasoning",
"summary": item.summary,
"encrypted_content": item.encrypted_content # <-- this is currently missing
}
References
Bug: Multi-turn tool call sessions fail with 404 for BYOK configurations when
storeisfalsebut reasoning item IDs are included in subsequent requestsSummary
When using a BYOK (Bring Your Own Key) configuration, the SDK sends multi-turn conversations using the Responses API — including prior
reasoningitems by ID in theinputarray — but explicitly setsstore: falseon each request. Because items are not persisted server-side whenstore: false, any subsequent turn that references a prior reasoning item ID receives a404 Invalid Requesterror, breaking all multi-turn agentic/tool-call flows.Reproduction
Prerequisites: This requires both a BYOK configuration and
wireApi=responsesto be set. WithoutwireApi=responses, the SDK routes through the Completions API and the issue does not occur.Any multi-turn conversation that involves tool use and reasoning will trigger this. Steps:
wireApi=responsesand a BYOK key.reasoning.effortset (e.g."medium"),store: false, andstream: true.reasoningitem with anrs_prefixed ID andencrypted_content(included viainclude: ["reasoning.encrypted_content"]).input.{ "error": { "message": "Item with id 'rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3' not found. Items are not persisted when `store` is set to false. Try again with `store` set to true, or remove this item from your input.", "type": "invalid_request_error", "param": "input", "code": null } }Request Trace (Simplified)
Turn 2 request body (the failing one):
{ "model": "gpt-5.2-chat-latest", "store": false, "stream": true, "include": ["reasoning.encrypted_content"], "reasoning": { "summary": "auto", "effort": "medium" }, "input": [ { "role": "user", "content": [...], "type": "message" }, { "id": "rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3", "type": "reasoning", "summary": [{ "text": "...", "type": "summary_text" }] }, { "type": "function_call", "id": "fc_call_5K9YT6DAU9wVqpZydr6eb8Rx", ... }, { "type": "function_call_output", "call_id": "call_5K9YT6DAU9wVqpZydr6eb8Rx", "output": "..." } ] }Note:
store: falseis explicitly set by the SDK in the outgoing request — it is not being forced by the server.Response:
HTTP 404Root Cause
The copilot cli is explicitly setting
store: falseon each request (confirmed in the request trace above). The cli then reconstructs multi-turn conversation history incorrectly.Per the [OpenAI Cookbook on reasoning items](https://cookbook.openai.com/examples/responses_api/reasoning_items), when
store: falseis used, reasoning items cannot be referenced by ID alone — the server has nothing persisted to resolve them against. The correct stateless pattern requires:include: ["reasoning.encrypted_content"]— the cli already does this ✅encrypted_contentblob populated — the cli is not doing this ❌Instead, the cli reconstructs the reasoning item in
inputwith onlyidandsummary, omittingencrypted_content. The server cannot resolve the ID (nothing was stored), hence the 404.The [Azure OpenAI Responses API documentation](https://learn.microsoft.com/en-us/azure/foundry/openai/how-to/responses?view=foundry-classic) states this explicitly:
The [OpenAI API Reference for the Responses object](https://platform.openai.com/docs/api-reference/responses) confirms that
encrypted_contentis the field that must be populated on reasoning items when operating statelessly.Expected Behavior
When
store: falseis set and a prior turn produced a reasoning item, the SDK must persist and replay the full reasoning item including theencrypted_contentfield in theinputarray on the next turn. Theidandsummaryalone are insufficient for stateless operation.Concretely, the reasoning item in the Turn 2
inputshould look like:{ "id": "rs_0c84b8e1b133e28101699289096d4881a29fa1d552619d53c3", "type": "reasoning", "summary": [{ "text": "...", "type": "summary_text" }], "encrypted_content": "<blob from turn 1 response>" }Impact
All multi-turn agentic conversations with reasoning enabled are broken for BYOK configurations. Any BYOK app using the SDK with tool use + reasoning will hit this on the second turn.
Environment
github/copilot-sdk(Python backend via GitHub Copilot SDK)/responseswireApi=responses+ BYOK keygpt-5.2-chat-latest{ "summary": "auto", "effort": "medium" }wireApi=responsesmulti-turn tool call session with reasoning enabledSuggested Fix
When serializing prior reasoning items into the
inputarray for the next turn, ensureencrypted_contentis captured from the prior response and included:References
encrypted_contentfield