Settings file watcher flushes network caches unconditionally, killing in-flight Bedrock streams through custom CA agents

Resolved 💬 2 comments Opened Apr 3, 2026 by aaaaaandrew Closed May 13, 2026

Summary

When ~/.claude/settings.json is modified during an active streaming API call, Claude Code's ConfigChange handler unconditionally clears the CA certificate, mTLS, and proxy agent caches. For users with custom CA certificates (via NODE_EXTRA_CA_CERTS), this destroys the HTTPS agent backing the in-flight stream, causing it to silently hang until the socket timeout fires. The subsequent fallback to non-streaming invoke then also times out repeatedly at large context sizes, making the session unresponsive for 15+ minutes.

Environment

  • Claude Code 2.1.84 (also confirmed on 2.1.91)
  • Bedrock provider (CLAUDE_CODE_USE_BEDROCK=1)
  • macOS, Node v24.3.0
  • Custom CA certificates via NODE_EXTRA_CA_CERTS (corporate TLS inspection proxy)

Steps to Reproduce

  1. Start Claude Code with NODE_EXTRA_CA_CERTS pointing to a custom CA bundle (e.g., corporate proxy root CA)
  2. Build up a large context window (100K+ tokens, ~400+ messages)
  3. While the model is actively streaming a response, trigger a settings.json write — the easiest way is to accept a permission prompt with "Always allow" (which persists the rule to settings.json)
  4. Observe: the active stream hangs silently for ~4-5 minutes, then falls back to non-streaming mode, which also times out repeatedly

What Happens (from debug log)

16:15:40  [API REQUEST] invoke-with-response-stream  (streaming starts normally)
16:15:43  Stream started - received first chunk
16:16:14  Detected change to ~/.claude/settings.json
16:16:14  Settings changed from userSettings, updating app state
16:16:14  Replacing all allow rules for destination 'userSettings' with 96 rule(s)
16:16:14  Cleared CA certificates cache
16:16:14  Cleared mTLS configuration cache
16:16:14  Cleared proxy agent cache
16:16:14  CA certs: useSystemCA=false, extraCertsPath=<custom-ca-bundle.pem>
16:16:14  mTLS: Creating HTTPS agent with custom certificates
          (in-flight stream is now orphaned — no data received)
16:20:32  [ERROR] Error streaming, falling back to non-streaming mode: The operation timed out.
16:20:33  [API REQUEST] invoke  (non-streaming fallback)
16:25:32  [ERROR] API error (attempt 1/11): undefined Request timed out.
16:30:32  [ERROR] API error (attempt 2/11): undefined Request timed out.
16:35:32  [ERROR] API error (attempt 3/11): undefined Request timed out.
16:38:40  [onCancel] (user manually cancelled after 23 minutes)

Root Cause

The settings change handler unconditionally flushes all network caches on any settings file change. This is triggered for ["userSettings", "flagSettings", "policySettings"] — so a permission rule write (which has no network relevance) flushes the same caches as a CA cert path change.

For users without custom CA certs, the flush is a no-op — the memoizers return undefined and no custom HTTPS agent exists. For users with NODE_EXTRA_CA_CERTS, the flush destroys the custom HTTPS agent that holds the corporate CA trust chain. In-flight connections through that agent are orphaned.

Compounding Issue: Non-streaming fallback timeout

After the stream dies, Claude Code falls back to invoke (non-streaming). At large context sizes (136K tokens in this case), Bedrock takes longer than 5 minutes to generate the full response synchronously. The client-side 5-minute timeout fires before the response arrives, causing repeated timeout retries (11 max attempts × 5 min each = potentially 55 minutes of silent hanging).

Streaming doesn't have this problem because the first chunk arrives in ~3 seconds, resetting the inactivity timer.

Suggested Fix

For the cache flush:

  • Only flush network caches (CA, mTLS, proxy) when network-relevant settings actually changed (env vars, cert paths, proxy config)
  • Permission rule changes, fast mode toggles, and plan mode changes should not trigger network cache invalidation

For the non-streaming fallback:

  • Consider retrying streaming instead of falling back to non-streaming invoke
  • If non-streaming fallback is kept, scale the timeout based on context size (136K tokens needs significantly more than 5 minutes for synchronous generation)

Who's Affected

This primarily impacts users with:

  • Corporate TLS inspection proxies (Zscaler, Netskope, etc.) that require NODE_EXTRA_CA_CERTS
  • Long-running sessions with large context windows
  • Active streaming interrupted by settings.json writes (permission acceptance, plan mode, etc.)

Users on direct Anthropic API without custom CA certs are unlikely to notice this bug.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗