Skip to content

fix(prover-client): do not send explicit content-length header to proof server#456

Merged
agronmurtezi merged 1 commit into
mainfrom
fix/prover-client-explicit-content-length
Jun 10, 2026
Merged

fix(prover-client): do not send explicit content-length header to proof server#456
agronmurtezi merged 1 commit into
mainfrom
fix/prover-client-explicit-content-length

Conversation

@agronmurtezi

Copy link
Copy Markdown
Collaborator

Problem

Proving fails with ClientError: Failed to prove transaction whenever the npm undici package (>= 8.2.0) is present in the process — e.g. in any test importing testcontainers or @effect/platform-node. Both "should prove a valid transaction" tests in httpProverClient.test.ts fail. This is the same regression that previously forced pinning undici back to 8.1.0 (d9531ec); the combined dependency updates re-introduce it by moving the pin to 8.4.x.

Root cause

Two things conspire:

  1. npm undici 8 hijacks global fetch on import. Its lib/global.js installs its own Agent as the global dispatcher at module load, including under the legacy Symbol.for('undici.globalDispatcher.1') slot that Node 22's bundled fetch (undici 6.24.1) reads. Merely importing testcontainers reroutes every fetch() in the process through npm undici 8 via a Dispatcher1Wrapper.
  2. undici 8.2.0 added strict content-length validation (fix: reject malformed content-length request headers nodejs/undici#5060, "reject malformed content-length request headers" — value must be a digit-only string). HttpClientRequest.bodyUint8Array from @effect/platform sets an explicit content-length header; Node's bundled fetch also computes one from the body, and the duplicated value arriving at undici 8's validator fails the check with InvalidArgumentError: invalid content-length header.

Verified in isolation: the same fetch POST with an explicit content-length header succeeds before import 'undici' and fails with invalid content-length header after it; without the explicit header it succeeds in both cases.

Fix

Build the proof-server request body with HttpBody.raw(body, { contentType: 'application/octet-stream' }) instead of bodyUint8Array, so no explicit content-length header is attached and fetch derives it from the body. This also matches the fetch spec, where Content-Length is a forbidden request header (browsers strip it silently anyway), and decouples the prover client from whichever undici version owns the global dispatcher.

This is the only place in the SDK that sends a request body through FetchHttpClient, so no other call sites are affected.

Testing

  • yarn test --filter=@midnight-ntwrk/wallet-sdk-prover-client --force: 11/11 pass (2 failed before the fix)
  • yarn turbo typecheck lint --filter=@midnight-ntwrk/wallet-sdk-prover-client: clean
  • Effect language-service diagnostics on the changed file: clean

…of server

undici >= 8.2.0 rejects malformed content-length request headers
(nodejs/undici#5060). When the npm undici package is installed as the
process-wide fetch dispatcher — a module-load side effect of importing
it transitively, e.g. via testcontainers or @effect/platform-node — the
explicit content-length header set by HttpClientRequest.bodyUint8Array
gets duplicated with the one Node's bundled fetch computes from the
body, and the combined value fails undici's digit-only validation,
making every proof-server request fail with 'invalid content-length
header'.

Build the request body with HttpBody.raw instead, which attaches no
content-length header and lets fetch derive it from the body. This also
matches the fetch spec, where Content-Length is a forbidden request
header.

@jtsang586 jtsang586 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@agronmurtezi agronmurtezi merged commit 7111b55 into main Jun 10, 2026
11 checks passed
@agronmurtezi agronmurtezi deleted the fix/prover-client-explicit-content-length branch June 10, 2026 13:04
dijnie pushed a commit to htlabs-xyz/midnight-wallet that referenced this pull request Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants