[BUG] Claude Code repeatedly retries after a mid-tool provider disconnect

Open 💬 1 comment Opened Jun 14, 2026 by N0zoM1z0

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

If the provider connection closes after a streamed tool call has been delivered but before a clean message completion, Claude Code repeatedly retries the same provider interaction instead of failing boundedly.

Severity / performance impact: High. A transient provider disconnect after tool-call delivery can create an unbounded retry loop and repeated local tool execution attempts.

Complete self-contained reproducer: https://gist.github.com/N0zoM1z0/885fa13bdb202b84b595050188174557

The Gist contains claude-post-tool-transient-disconnect.reproduce.py. Download and run:

gh gist clone 885fa13bdb202b84b595050188174557 claude-post-tool-transient-disconnect-reproducer
cd claude-post-tool-transient-disconnect-reproducer
python3 claude-post-tool-transient-disconnect.reproduce.py

To reuse an already-built local image:

python3 claude-post-tool-transient-disconnect.reproduce.py --skip-build

Complete self-contained reproducer: reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py

Run from this repository checkout:

python3 reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py

To reuse an already-built local image:

python3 reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py --skip-build

Key output from a local run against the affected version:

provider_requests=1201
closed_mid_stream=1201
process_timed_out=True
REPRODUCED

The reproducer builds Claude Code from the public npm package and runs Docker with 2 CPUs and 4 GiB RAM by default.

What Should Happen?

Claude Code should cap retries and preserve enough turn state to avoid repeatedly treating the same partial streamed tool call as a fresh action.

Error Messages/Logs

closed_mid_stream=1201
process_timed_out=True
REPRODUCED

Steps to Reproduce

  1. Run the self-contained reproducer.
  2. The local mock provider streams a Bash tool call and then closes the SSE connection mid-stream.
  3. Observe repeated provider requests until the reproducer timeout.

Complete self-contained reproducer: https://gist.github.com/N0zoM1z0/885fa13bdb202b84b595050188174557

The Gist contains claude-post-tool-transient-disconnect.reproduce.py. Download and run:

gh gist clone 885fa13bdb202b84b595050188174557 claude-post-tool-transient-disconnect-reproducer
cd claude-post-tool-transient-disconnect-reproducer
python3 claude-post-tool-transient-disconnect.reproduce.py

To reuse an already-built local image:

python3 claude-post-tool-transient-disconnect.reproduce.py --skip-build

Complete self-contained reproducer: reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py

Run from this repository checkout:

python3 reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py

To reuse an already-built local image:

python3 reports/claude-code/claude-post-tool-transient-disconnect.reproduce.py --skip-build

Key output from a local run against the affected version:

provider_requests=1201
closed_mid_stream=1201
process_timed_out=True
REPRODUCED

The reproducer builds Claude Code from the public npm package and runs Docker with 2 CPUs and 4 GiB RAM by default.

Claude Model

Other

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.175

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Non-interactive/CI environment

Additional Information

The mock provider is local and deterministic; no external model call is required.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗