Skip to content

fix(devframe): stop mcp-http tests from sharing a port#86

Merged
antfu merged 1 commit into
mainfrom
fix/mcp-http-flaky-test
Jul 10, 2026
Merged

fix(devframe): stop mcp-http tests from sharing a port#86
antfu merged 1 commit into
mainfrom
fix/mcp-http-flaky-test

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

What

mcp-http.test.ts was flaking CI's unit-test job on every platform/Node version, always failing on a fetch failed / SocketError: other side closed.

Root cause

Every test in the file booted its dev server via createDevServer without an explicit port, so each boot() bound to the same default port (9999). Since all five tests run in the same Node process, Node's global fetch() (undici) pools keep-alive sockets per origin (http://127.0.0.1:9999) — it has no idea the server behind that origin was torn down and replaced by a fresh instance between tests.

Two failure shapes fell out of this:

  • A later test's fetch() could get handed a stale, already-dead socket left over from an earlier (now-closed) test's server, failing near-instantly with a socket error.
  • Or the earlier server's close() would hang for ~4 seconds (undici's default client-side keepAliveTimeout) waiting for the client to release an idle pooled socket before the underlying connection could actually end.

Confirmed locally: the specific test failed ~50% of repeated runs before the fix, and 0/50 after.

Fix

Pass port: 0 to each createDevServer call in the test file so the OS assigns a fresh ephemeral port per test, eliminating the origin collision entirely. Test-only change — no production code touched.

Verification

  • mcp-http.test.ts run 50 times in a loop: 0 failures (was ~50% failure rate before).
  • pnpm build && pnpm test: 63/63 test files, 642/642 tests pass.
  • pnpm lint: clean.
  • pnpm typecheck: clean.

🤖 This PR was created with the help of an agent (opencode).

Every test in mcp-http.test.ts booted its dev server on the same
default port (9999). Since Node's global fetch() (undici) pools
keep-alive sockets per origin, a later test could get handed a
stale socket left over from an earlier test's already-closed
server — failing instantly with a socket error, or leaving the
earlier server's close() hanging until undici's keep-alive
timeout released it. This was flaking CI's unit-test job on
every platform/Node version.

Pass port: 0 so each boot() gets a fresh OS-assigned port,
eliminating the origin collision entirely.

🤖 Generated with an agent (opencode).
@netlify

netlify Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit aa97562
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a505e81da674a00089404ce
😎 Deploy Preview https://deploy-preview-86--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@antfu antfu merged commit 36cde4e into main Jul 10, 2026
12 checks passed
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