The server tools docs say to handle pause_turn by passing the response back as-is:
"Pass the paused response back as-is in a subsequent request to let Claude continue its turn."
When we do exactly that, we get a 400. Wanted to check if we're misunderstanding something.
What happens
- API returns
pause_turn with an unpaired server_tool_use block (no web_search_tool_result)
- We re-submit with that content in the assistant turn — serialized correctly as
{"type": "server_tool_use", ...} (verified via SDK's _transform.py)
- API rejects with:
messages.1: `web_search` tool use with id `srvtoolu_01UkjByNZ6pFvVLGAjWnYBjt`
was found without a corresponding `web_search_tool_result` block
The API's own validator is rejecting the block that the API itself produced and told us to send back.
Questions
- Is there something the docs are missing — a flag, header, or different message structure required for
pause_turn resumption?
- Does this behave differently with
web_search_20260209?
- Does re-submission only work when resetting to
[user, paused_assistant] (as in the docs example), and not when appending to a multi-turn history?
Current workaround
We strip server_tool_use blocks before re-submitting, letting the model re-issue the search from scratch. This avoids the 400 but likely abandons any in-flight search state. Happy to be corrected if there's a proper way to handle this.
The server tools docs say to handle
pause_turnby passing the response back as-is:When we do exactly that, we get a 400. Wanted to check if we're misunderstanding something.
What happens
pause_turnwith an unpairedserver_tool_useblock (noweb_search_tool_result){"type": "server_tool_use", ...}(verified via SDK's_transform.py)The API's own validator is rejecting the block that the API itself produced and told us to send back.
Questions
pause_turnresumption?web_search_20260209?[user, paused_assistant](as in the docs example), and not when appending to a multi-turn history?Current workaround
We strip
server_tool_useblocks before re-submitting, letting the model re-issue the search from scratch. This avoids the 400 but likely abandons any in-flight search state. Happy to be corrected if there's a proper way to handle this.