sanitizeMessage drops OpenAI reasoning ids but keeps provider-executed web_search parts; the next Responses request fails with "Item 'ws_…' of type 'web_search_call' was provided without its required 'reasoning' item" · Issue #2639 · cloudflare/agents · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sanitizeMessage drops OpenAI reasoning ids but keeps provider-executed web_search parts; the next Responses request fails with "Item 'ws_…' of type 'web_search_call' was provided without its required 'reasoning' item" #2639
Versions:agents 0.28.1, @cloudflare/think 0.20.2, ai 7.0.145 and @ai-sdk/openai 4.0.97. Still reproduces on agents 0.29.0, ai 7.0.147 and @ai-sdk/openai 4.0.98. mainsessions/sanitize.ts is unchanged.
What happens
A reasoning model (here gpt-6-luna, through the Responses API, store at its default) uses openai.tools.webSearch(). The assistant message streams a reasoning part (providerMetadata.openai.itemId: "rs_…") and then a provider-executed tool-web_search part whose toolCallId is the ws_… item id. Every Sessions write runs sanitizeMessage(), which:
strips openai.itemId and reasoningEncryptedContent from every part, then
drops a reasoning part that is left with no text and no metadata.
When the reasoning has summary text, the part survives but without an itemId. @ai-sdk/openai then skips it ("Non-OpenAI reasoning parts are not supported"). Either way the next request has no reasoning item. The web_search result is still sent as {type: "item_reference", id: <toolCallId>}, because the provider uses toolCallId when itemId is missing. OpenAI rejects a web_search_call reference without the reasoning item that preceded it, so every later turn in that conversation fails.
Reproduction (Node, no network: the request body is captured by a custom fetch)
The second request references ws_456 without rs_123. This happens both with empty reasoning text and with summary text.
Seen live: on gpt-6-luna, every turn after some web_search turns failed with Item 'ws_…' of type 'web_search_call' was provided without its required 'reasoning' item. The stored assistant message had a tool-web_search part and no reasoning part. /new, or undoing that turn, recovered.
Or, when sanitizing removes or orphans a reasoning item, also neutralise the provider-executed tool-web_search (and similar) parts that follow it in the same step, for example by dropping them and keeping the text, so no orphan item_reference is sent.
Activity