[Bug] v0.8.0: setGlobalDispatcher(EnvHttpProxyAgent({ bodyTimeout: 0, headersTimeout: 0 })) disables ALL HTTP timeouts — a never-answering provider hangs the turn indefinitely #2297
claudegoogl-sudo
started this conversation in
Bug reports
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Affected area
AI providers and models
Coding agent and CLI
What happened?
The CLI bundle installs a global undici dispatcher with all HTTP timeouts disabled:
(
dist/bundle/cli-main-JLBZR3DA.js, same line in the unbundleddist/cli-main.js, v0.8.0 / UA 2.1.258.)With the dispatcher at
0/0, any provider request that is accepted but never answered hangs the turn indefinitely, because:new Anthropic({ apiKey: null, authToken, baseURL, ... }), notimeout, no customfetch) only bounds time-to-headers via its per-request default (10 min) — and a stalled response body (idle SSE stream) is unbounded;fetchcalls that carry noAbortSignal(e.g. the OpenAI Codex token exchange/refresh in the bundled OAuth module) are fully unbounded.Production observation (headless, Linux, v0.8.0): a single
anthropic-messagescall emittedturn_startand then produced no events for 3 h 13 m; the request eventually completed with a401 OAuth access token has expired— i.e. the client had been parked on the response the entire time. The CLI's own auto-retry then recovered the session in under 6 s once the failure finally surfaced. Related symptom report: #2093.Steps to reproduce
Deterministic (no usage-window dependence):
~/.prime/agent/models.json(api: "anthropic-messages",baseUrl: http://127.0.0.1:<port>).--mode json) with that provider and any prompt.turn_startis emitted, then silence — nomessage_end, no error, no retry, for as long as you care to wait (we observed 3 h 13 m in production before the provider finally answered).Expected behavior
headersTimeout: 60_000), surfacing the CLI's normal provider-failure path so the existing auto-retry can take over.bodyTimeout: 600_000) — reset on every chunk, so healthy long streams are unaffected.Actual behavior
With
bodyTimeout: 0, headersTimeout: 0the request waits forever; the turn emits nothing; the only recovery is the provider eventually responding or the process being killed externally.Prime Agent version
0.8.0
Installation method
npm package
Operating system
Linux
Operating system version
Ubuntu 24.04 (kernel 6.8)
CPU architecture
x86_64 / amd64
Shell and terminal
bash, non-interactive headless (CLI driven by automation)
Additional context
We validated the fix on a vendored copy by changing only the two numeric arguments:
Measured against the never-responding mock above:
UND_ERR_HEADERS_TIMEOUT, surfaced as the CLI's "Request timed out." provider error) instead of hanging — verified from the mock side: the client disconnects at ~60 s while the mock would happily hold the socket open;bodyTimeout: 600_000;setGlobalDispatcherwrites the sharedSymbol.for("undici.globalDispatcher.1")registry slot that Node's globalfetchalso reads, this additionally bounds the credential-path fetches that have noAbortSignalof their own (e.g. the bundled OpenAI Codex token refresh; the Anthropic OAuthpostJsonalready carriesAbortSignal.timeout(30_000)).If zero-timeout semantics are intentional for some environment (very slow proxies?), making the two numbers configurable (env vars) would keep that possible without defaulting every hop to unbounded.
All reactions