Problem
In src/common/net/fetch-client.ts (~lines 212–214), the per-request timeout's clearTimeout fires as soon as fetch resolves — i.e., when headers arrive. Reading the response body after that has no deadline, so a server that sends headers promptly but streams the body slowly (or stalls mid-body) can hang the SDK call indefinitely despite a configured options.timeout.
Suggested fix
Keep the per-request AbortController (created at ~lines 192–195) armed until the body is fully consumed, or apply a separate body-read deadline, instead of clearing the timer on header receipt.
Related minor nit (same file)
toJSON() (~lines 431–435) returns null without draining the body when the content-type isn't JSON, leaving the response unconsumed. Undici destroys that socket (safe), but it's wasted connection churn — draining or explicitly cancelling the body would be cleaner. Could be fixed in the same pass.
Problem
In
src/common/net/fetch-client.ts(~lines 212–214), the per-request timeout'sclearTimeoutfires as soon asfetchresolves — i.e., when headers arrive. Reading the response body after that has no deadline, so a server that sends headers promptly but streams the body slowly (or stalls mid-body) can hang the SDK call indefinitely despite a configuredoptions.timeout.Suggested fix
Keep the per-request
AbortController(created at ~lines 192–195) armed until the body is fully consumed, or apply a separate body-read deadline, instead of clearing the timer on header receipt.Related minor nit (same file)
toJSON()(~lines 431–435) returnsnullwithout draining the body when the content-type isn't JSON, leaving the response unconsumed. Undici destroys that socket (safe), but it's wasted connection churn — draining or explicitly cancelling the body would be cleaner. Could be fixed in the same pass.