content-length header collision → InvalidArgumentError: invalid content-length header when a custom undici global dispatcher is installed

Open Beginner friendly
#197 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
85/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
node.js, typescript
Domain
api, backend

Research direction

Start in core.js at APIClient.buildHeaders(), around line 250, and inspect how content-length is added when a body is present. Reproduce the POST /v1/sessions request with a custom undici global dispatcher, then verify that the request succeeds without the invalid header error after the header handling is corrected.

Written by the indexing model from the issue text.

Description

Description

@browserbasehq/sdk@2.16.0's APIClient.buildHeaders() (in core.js) explicitly sets a content-length header on outgoing requests before handing the request to fetch. When the consuming application has installed a custom global dispatcher via undici's setGlobalDispatcher() (e.g. to raise the connect timeout — setGlobalDispatcher(new Agent({ connect: { timeout: ... } }))), undici's Request constructor folds the SDK's caller-supplied content-length header together with its own internally computed one into a comma-joined value (observed: "52, 52"), which fails undici's digit-only header validation.

This crashes every POST /v1/sessions call (session creation) for any consumer that installs a non-default undici dispatcher — a common pattern for adjusting timeouts, proxies, or connection pooling.

Reproduction
import Browserbase from "@browserbasehq/sdk";
import { Agent, setGlobalDispatcher } from "undici";

setGlobalDispatcher(new Agent({ connect: { timeout: 120_000 } }));

const bb = new Browserbase({ apiKey: "..." });
await bb.sessions.create({ projectId: "..." });
Error
FETCH FAILED for URL: https://api.browserbase.com/v1/sessions
CAUSE: InvalidArgumentError: invalid content-length header
  at processHeader (undici/lib/core/request.js:514:13)
  at new Request (undici/lib/core/request.js:264:11)
  ...
  code: 'UND_ERR_INVALID_ARG'
Root cause

APIClient.buildHeaders() sets reqHeaders['content-length'] = contentLength unconditionally when a body is present (core.js, ~line 250). Under a custom dispatcher, undici's Request constructor doesn't dedupe this against the header it computes itself from the real body length the way the default dispatcher's H1 client path does — the two values get folded together at Request construction time, before undici's own H1-client-level content-length recompute-and-rewrite logic (which would correctly override a single caller-supplied value) ever runs.

Environment
  • @browserbasehq/sdk@2.16.0
  • undici@8.8.0 (also reproduces on 8.9.0)
  • Node 22.14.0
Suggested fix

Don't set content-length explicitly in buildHeaders() — let fetch/undici compute it from the request body, which it does correctly and exactly once. We've verified removing that one assignment resolves the crash with no other side effects.

Workaround

We're currently working around this downstream by monkeypatching APIClient.prototype.buildHeaders at runtime to strip the contentLength argument before it reaches the header-building logic.

Dominant language
TypeScript
Stars
64
Forks
17
Avg merge
13m
Merged PRs (30d)
4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from browserbase/sdk-node

All issues in browserbase/sdk-node

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.