Follow Discord
Sweep 06 Nov 2026 · 01:32Z Build v2.1.319 537 read Stable v2.1.311 Latest v2.1.319 Next v2.1.319 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

handling-stop-reasons changedbuild-with-claude/handling-stop-reasons

Nearest release: v2.1.315, published under an hour before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+219added
Lines−118removed
From line 2,326 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits26to this page, all time

The whole hunk

from line 2326, old and new numbered
/
lines
from line 2326
23262326 
23272327### Implement retry logic for pause\_turn
23282328 
2329When you use [server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools), the API might return `pause_turn` if the server-side sampling loop reaches its iteration limit (default 10). Handle this by continuing the conversation:
2329When you use [server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools), the API might return `pause_turn` if the server-side sampling loop reaches its iteration limit (default 10). Handle this by adding the paused response to your messages unchanged and sending the request again. If the response includes a `container`, [send its ID back](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse) as well. Without it, the next request starts a new container, and files from earlier in the turn are lost.
23302330 
2331<CodeGroup exclude="shell">
2331<CodeGroup exclude="shell:cURL, shell:CLI">
2332 <CodeGroupItem language="cURL">
2333 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
2334 </CodeGroupItem>
2335 
2336 <CodeGroupItem language="CLI">
2337 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
2338 </CodeGroupItem>
2339 
23322340 ```python Python
2333 def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
2334 """
2335 Handle server tool conversations that might require multiple continuations.
2341 client = anthropic.Anthropic()
23362342 
2337 The server uses a sampling loop to run server tools. If the loop
2338 reaches its iteration limit, the API returns pause_turn. Continue the
2339 conversation by sending the response back to let Claude finish.
2340 """
2343 
2344 def handle_server_tool_conversation(client, user_query, tools, max_requests=5):
23412345 messages = [{"role": "user", "content": user_query}]
2346 container_id = None
23422347 
2343 for _ in range(max_continuations):
2348 for _ in range(max_requests):
23442349 response = client.messages.create(
23452350 model="claude-opus-5-5",
23462351 max_tokens=4096,
23472352 messages=messages,
23482353 tools=tools,
2354 container=container_id,
23492355 )
23502356 
23512357 if response.stop_reason != "pause_turn":
2352 # Claude finished processing: return the final response
2358 # Not paused: return the response
23532359 return response
23542360 
2355 # pause_turn: replace the full message list to maintain alternating roles
2356 messages = [
2357 {"role": "user", "content": user_query},
2358 {"role": "assistant", "content": response.content},
2359 ]
2361 # pause_turn: add the paused response as an assistant message, then continue
2362 messages.append({"role": "assistant", "content": response.content})
23602363 
2361 # Reached max continuations: return the last response
2364 # If the tools ran in a container, send its ID back so its files are kept
2365 if response.container:
2366 container_id = response.container.id
2367 
2368 # Still paused after max_requests requests: return the last response
23622369 return response
2370 
2371 
2372 response = handle_server_tool_conversation(
2373 client,
2374 "Use the code execution tool to find the 1,000th prime number.",
2375 [{"type": "code_execution_20250825", "name": "code_execution"}],
2376 )
2377 print(response.stop_reason)
23632378 ```
23642379 
23652380 ```typescript TypeScript
2381 const client = new Anthropic();
2382 
23662383 async function handleServerToolConversation(
23672384 client: Anthropic,
23682385 userQuery: string,
23692386 tools: Anthropic.ToolUnion[],
2370 maxContinuations = 5
2387 maxRequests = 5
23712388 ): Promise<Anthropic.Message> {
2372 let messages: Anthropic.MessageParam[] = [{ role: "user", content: userQuery }];
2389 const messages: Anthropic.MessageParam[] = [{ role: "user", content: userQuery }];
2390 let containerId: string | null = null;
23732391 let response: Anthropic.Message;
2392 let requestCount = 0;
23742393 
2375 for (let i = 0; i < maxContinuations; i++) {
2394 do {
23762395 response = await client.messages.create({
23772396 model: "claude-opus-5-5",
23782397 max_tokens: 4096,
23792398 messages,
2380 tools
2399 tools,
2400 container: containerId
23812401 });
23822402 
23832403 if (response.stop_reason !== "pause_turn") {
2384 // Claude finished processing: return the final response
2404 // Not paused: return the response
23852405 return response;
23862406 }
23872407 
2388 // pause_turn: replace the full message list to maintain alternating roles
2389 messages = [
2390 { role: "user", content: userQuery },
2391 { role: "assistant", content: response.content }
2392 ];
2393 }
2408 // pause_turn: add the paused response as an assistant message, then continue
2409 messages.push({ role: "assistant", content: response.content });
23942410 
2395 // Reached max continuations: return the last response
2396 return response!;
2411 // If the tools ran in a container, send its ID back so its files are kept
2412 if (response.container) {
2413 containerId = response.container.id;
2414 }
2415 } while (++requestCount < maxRequests);
2416 
2417 // Still paused after maxRequests requests: return the last response
2418 return response;
23972419 }
2420 
2421 const response = await handleServerToolConversation(
2422 client,
2423 "Use the code execution tool to find the 1,000th prime number.",
2424 [{ type: "code_execution_20250825", name: "code_execution" }]
2425 );
2426 console.log(response.stop_reason);
23982427 ```
23992428 
24002429 ```csharp C#
2430 // A server tool turn can run for minutes, longer than the SDK's default timeout,
2431 // which it sets from MaxTokens (about 2 minutes at 4096).
2432 AnthropicClient client = new() { Timeout = TimeSpan.FromMinutes(10) };
2433 
24012434 static async Task<Message> HandleServerToolConversation(
24022435 AnthropicClient client,
24032436 string userQuery,
24042437 List<ToolUnion> tools,
2405 int maxContinuations = 5)
2438 int maxRequests = 5)
24062439 {
24072440 List<MessageParam> messages = [new UserMessageParam { Content = userQuery }];
2408 Message response = null!;
2441 MessageCreateParamsContainer? container = null;
2442 Message response;
2443 var requestCount = 0;
24092444 
2410 for (var i = 0; i < maxContinuations; i++)
2445 do
24112446 {
24122447 response = await client.Messages.Create(new MessageCreateParams
24132448 {
from line 2449
24142449 Model = Model.ClaudeOpus5_5,
24152450 MaxTokens = 4096,
24162451 Messages = messages,
2417 Tools = tools
2452 Tools = tools,
2453 Container = container
24182454 });
24192455 
2420 if (response.StopReason != "pause_turn")
2456 if (response.StopReason != StopReason.PauseTurn)
24212457 {
2422 // Claude finished processing: return the final response
2458 // Not paused: return the response
24232459 return response;
24242460 }
24252461 
2426 // pause_turn: replace the full message list to maintain alternating roles
2427 messages =
2428 [
2429 new UserMessageParam { Content = userQuery },
2430 new AssistantMessageParam
2431 {
2432 Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
2433 }
2434 ];
2435 }
2462 // pause_turn: add the paused response as an assistant message, then continue
2463 // Request and response blocks are separate types: copy each block's JSON unchanged
2464 messages.Add(new AssistantMessageParam
2465 {
2466 Content = response.Content.Select(block => new ContentBlockParam(block.Json)).ToList()
2467 });
24362468 
2437 // Reached max continuations: return the last response
2469 // If the tools ran in a container, send its ID back so its files are kept
2470 if (response.Container is not null)
2471 {
2472 container = response.Container.ID;
2473 }
2474 } while (++requestCount < maxRequests);
2475 
2476 // Still paused after maxRequests requests: return the last response
24382477 return response;
24392478 }
2479 
2480 var response = await HandleServerToolConversation(
2481 client,
2482 "Use the code execution tool to find the 1,000th prime number.",
2483 [new CodeExecutionTool20250825()]);
2484 Console.WriteLine(response.StopReason?.Raw());
24402485 ```
24412486 
24422487 ```go Go
from line 2489
24442489 client anthropic.Client,
24452490 userQuery string,
24462491 tools []anthropic.ToolUnionParam,
2447 maxContinuations int,
2492 maxRequests int,
24482493 ) (*anthropic.Message, error) {
2449 messages := []anthropic.MessageParam{anthropic.NewUserMessage(anthropic.NewTextBlock(userQuery))}
2494 messages := []anthropic.MessageParam{
2495 anthropic.NewUserMessage(anthropic.NewTextBlock(userQuery)),
2496 }
2497 var container anthropic.MessageCreateParamsContainerUnion
24502498 var response *anthropic.Message
24512499 var err error
24522500 
2453 for range maxContinuations {
2501 for range maxRequests {
24542502 response, err = client.Messages.New(context.TODO(), anthropic.MessageNewParams{
24552503 Model: anthropic.ModelClaudeOpus5_5,
24562504 MaxTokens: 4096,
24572505 Messages: messages,
24582506 Tools: tools,
2507 Container: container,
24592508 })
24602509 if err != nil {
24612510 return nil, err
24622511 }
24632512 
2464 if response.StopReason != "pause_turn" {
2465 // Claude finished processing: return the final response
2513 if response.StopReason != anthropic.StopReasonPauseTurn {
2514 // Not paused: return the response
24662515 return response, nil
24672516 }
24682517 
2469 // pause_turn: replace the full message list to maintain alternating roles
2470 var contentParams []anthropic.ContentBlockParamUnion
2471 for _, block := range response.Content {
2472 contentParams = append(contentParams, block.ToParam())
2518 // pause_turn: add the paused response as an assistant message, then continue
2519 messages = append(messages, response.ToParam())
2520 
2521 // If the tools ran in a container, send its ID back so its files are kept
2522 if response.Container.ID != "" {
2523 container.OfString = anthropic.String(response.Container.ID)
24732524 }
2474 messages = []anthropic.MessageParam{
2475 anthropic.NewUserMessage(anthropic.NewTextBlock(userQuery)),
2476 anthropic.NewAssistantMessage(contentParams...),
2477 }
24782525 }
24792526 
2480 // Reached max continuations: return the last response
2527 // Still paused after maxRequests requests: return the last response
24812528 return response, nil
24822529 }
2530 
2531 func main() {
2532 client := anthropic.NewClient()
2533 
2534 response, err := handleServerToolConversation(
2535 client,
2536 "Use the code execution tool to find the 1,000th prime number.",
2537 []anthropic.ToolUnionParam{
2538 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},
2539 },
2540 5,
2541 )
2542 if err != nil {
2543 log.Fatal(err)
2544 }
2545 fmt.Println(response.StopReason)
2546 }
24832547 ```
24842548 
24852549 ```java Java
2486 static Message handleServerToolConversation(
2550 Message handleServerToolConversation(
24872551 AnthropicClient client,
24882552 String userQuery,
2489 List<Tool> tools,
2490 int maxContinuations
2553 List<ToolUnion> tools,
2554 int maxRequests
24912555 ) {
2556 var params = MessageCreateParams.builder()
2557 .model(Model.CLAUDE_OPUS_5_5)
2558 .maxTokens(4096L)
2559 .tools(tools)
2560 .addUserMessage(userQuery);
24922561 Message response = null;
24932562 
2494 for (int i = 0; i < maxContinuations; i++) {
2495 // Rebuild the params each iteration so messages aren't accumulated
2496 MessageCreateParams.Builder params = MessageCreateParams.builder()
2497 .model(Model.CLAUDE_OPUS_5_5)
2498 .maxTokens(4096L)
2499 .addUserMessage(userQuery);
2500 tools.forEach(params::addTool);
2501 if (response != null) {
2502 params.addMessage(response);
2503 }
2504 
2563 for (int request = 0; request < maxRequests; request++) {
25052564 response = client.messages().create(params.build());
25062565 
2507 if (!response.stopReason().map(StopReason.PAUSE_TURN::equals).orElse(false)) {
2508 // Claude finished processing: return the final response
2566 boolean paused = response.stopReason().filter(StopReason.PAUSE_TURN::equals).isPresent();
2567 if (!paused) {
2568 // Not paused: return the response
25092569 return response;
25102570 }
2511 // pause_turn: loop again and send the response back
2571 
2572 // pause_turn: add the paused response as an assistant message, then continue
2573 params.addMessage(response);
2574 
2575 // If the tools ran in a container, send its ID back so its files are kept
2576 response.container().ifPresent(container -> params.container(container.id()));
25122577 }
25132578 
2514 // Reached max continuations: return the last response
2579 // Still paused after maxRequests requests: return the last response
25152580 return response;
25162581 }
2582 
2583 void main() {
2584 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
2585 
2586 Message response = handleServerToolConversation(
2587 client,
2588 "Use the code execution tool to find the 1,000th prime number.",
2589 List.of(ToolUnion.ofCodeExecutionTool20250825(CodeExecutionTool20250825.builder().build())),
2590 5
2591 );
2592 response.stopReason().ifPresent(IO::println);
2593 }
25172594 ```
25182595 
25192596 ```php PHP
2597 $client = new Client();
2598 
25202599 function handle_server_tool_conversation(
25212600 Client $client,
25222601 string $userQuery,
25232602 array $tools,
2524 int $maxContinuations = 5
2525 ) {
2603 int $maxRequests = 5,
2604 ): Message {
25262605 $messages = [['role' => 'user', 'content' => $userQuery]];
2527 $response = null;
2606 $containerId = null;
2607 $requestCount = 0;
25282608 
2529 for ($i = 0; $i < $maxContinuations; $i++) {
2609 do {
25302610 $response = $client->messages->create(
25312611 maxTokens: 4096,
25322612 messages: $messages,
2533 model: 'claude-opus-5-5',
2613 model: Model::CLAUDE_OPUS_5_5,
25342614 tools: $tools,
2615 container: $containerId,
25352616 );
25362617 
2537 if ($response->stopReason !== 'pause_turn') {
2538 // Claude finished processing: return the final response
2618 if ($response->stopReason !== StopReason::PAUSE_TURN->value) {
2619 // Not paused: return the response
25392620 return $response;
25402621 }
25412622 
2542 // pause_turn: replace the full message list to maintain alternating roles
2543 $messages = [
2544 ['role' => 'user', 'content' => $userQuery],
2545 ['role' => 'assistant', 'content' => $response->content],
2546 ];
2547 }
2623 // pause_turn: add the paused response as an assistant message, then continue
2624 $messages[] = ['role' => 'assistant', 'content' => $response->content];
25482625 
2549 // Reached max continuations: return the last response
2626 // If the tools ran in a container, send its ID back so its files are kept
2627 $containerId = $response->container->id ?? $containerId;
2628 } while (++$requestCount < $maxRequests);
2629 
2630 // Still paused after $maxRequests requests: return the last response
25502631 return $response;
25512632 }
2633 
2634 $response = handle_server_tool_conversation(
2635 $client,
2636 'Use the code execution tool to find the 1,000th prime number.',
2637 [new CodeExecutionTool20250825()],
2638 );
2639 echo $response->stopReason, PHP_EOL;
25522640 ```
25532641 
25542642 ```ruby Ruby
2555 def handle_server_tool_conversation(client, user_query, tools, max_continuations: 5)
2643 client = Anthropic::Client.new
2644 
2645 def handle_server_tool_conversation(client, user_query, tools, max_requests: 5)
25562646 messages = [{ role: "user", content: user_query }]
2647 container_id = nil
25572648 response = nil
25582649 
2559 max_continuations.times do
2650 max_requests.times do
25602651 response = client.messages.create(
2561 model: "claude-opus-5-5",
2652 model: Anthropic::Model::CLAUDE_OPUS_5_5,
25622653 max_tokens: 4096,
2563 messages: messages,
2564 tools: tools
2654 messages:,
2655 tools:,
2656 container: container_id
25652657 )
25662658 
2567 # Claude finished processing: return the final response
2659 # Not paused: return the response
25682660 return response unless response.stop_reason == :pause_turn
25692661 
2570 # pause_turn: replace the full message list to maintain alternating roles
2571 messages = [
2572 { role: "user", content: user_query },
2573 { role: "assistant", content: response.content }
2574 ]
2662 # pause_turn: add the paused response as an assistant message, then continue
2663 messages << { role: "assistant", content: response.content }
2664 
2665 # If the tools ran in a container, send its ID back so its files are kept
2666 container_id = response.container&.id || container_id
25752667 end
25762668 
2577 # Reached max continuations: return the last response
2669 # Still paused after max_requests requests: return the last response
25782670 response
25792671 end
2672 
2673 response = handle_server_tool_conversation(
2674 client,
2675 "Use the code execution tool to find the 1,000th prime number.",
2676 [Anthropic::CodeExecutionTool20250825.new]
2677 )
2678 puts response.stop_reason
25802679 ```
25812680</CodeGroup>
2681 
2682The function returns the last response, which holds only the final part of the turn. To show the whole turn or to continue the conversation, keep the paused responses as well.
25822683 
25832684## Stop reasons versus errors
25842685 
Feedback