Affected versions
@commercetools/ts-client@4.9.1 (likely earlier)
Environment
- Node.js 24.11.0
httpClient: fetch (Node global / undici-backed)
Problem
In createHttpMiddleware$1, every body-bearing request unconditionally sets:
requestHeader['Content-Length'] = byteLength(body);
When httpClient: fetch is configured, this becomes redundant because the fetch runtime computes Content-Length from the request body itself.
Under Node 24's bundled fetch, the manual value gets duplicated: bundled fetch's auto-Content-Length step appends its computed value on top of the user-supplied one, and HeadersList.append joins them with ", ".
The result is e.g. "666, 666".
When npm undici 8.2.0+ is also installed (in the case of commercetools Checkout) which it commonly is, transitively, and which auto-installs itself as the global dispatcher via lib/global.js its stricter processHeader (PR nodejs/undici#5060) rejects the joined string, throwing:
InvalidArgumentError: invalid content-length header
at processHeader (undici/lib/core/request.js:503)
at new Request (undici/lib/core/request.js:264)
Suggested fix
Don't set Content-Length manually when the configured httpClient is fetch-shaped. The fetch spec dictates the runtime computes it, and any user-supplied value is at best redundant and at worst (as here) actively harmful.
If a manual value is still needed for axios compat, gate it on httpClient !== fetch / httpClient.name !== 'fetch', or move it behind an opt-in option.
Wdyt?
Affected versions
@commercetools/ts-client@4.9.1(likely earlier)Environment
httpClient: fetch(Node global / undici-backed)Problem
In
createHttpMiddleware$1, every body-bearing request unconditionally sets:When
httpClient: fetchis configured, this becomes redundant because the fetch runtime computes Content-Length from the request body itself.Under Node 24's bundled fetch, the manual value gets duplicated: bundled fetch's auto-Content-Length step appends its computed value on top of the user-supplied one, and HeadersList.append joins them with ", ".
The result is e.g.
"666, 666".When npm undici 8.2.0+ is also installed (in the case of commercetools Checkout) which it commonly is, transitively, and which auto-installs itself as the global dispatcher via lib/global.js its stricter processHeader (PR nodejs/undici#5060) rejects the joined string, throwing:
Suggested fix
Don't set Content-Length manually when the configured
httpClientis fetch-shaped. The fetch spec dictates the runtime computes it, and any user-supplied value is at best redundant and at worst (as here) actively harmful.If a manual value is still needed for axios compat, gate it on httpClient !== fetch / httpClient.name !== 'fetch', or move it behind an opt-in option.
Wdyt?