cloudflare / cloudflare/workers-sdk

@cloudflare/vitest-pool-workers segfaults with 3+ real auxiliary Workers wired together (version-independent, minimal synthetic repro does not reproduce)

Open
#14,945 3 comments 0 reactions 0 assignees View on GitHub
feature:multiworker package:vitest
Dominant language
TypeScript
Stars
4.5k
Forks
1.5k
Avg merge
3d 8h
Merged PRs (30d)
186

Description

### Which Cloudflare product(s) does this pertain to?

Workers - Wrangler, Vitest-based testing tools

### What version(s) of the tool(s) are you using?

- `@cloudflare/vitest-pool-workers`: 0.18.8 AND 0.19.1 (latest at time of filing) — same crash, same signature on both
- `miniflare`: 4.20260722.0 (bundled by 0.18.8) AND 4.20260730.0 (bundled by 0.19.1)
- `workerd`: 1.20260722.1 AND 1.20260730.1
- `wrangler`: 4.100.0 (also reproduced against 4.114.0)
- `vitest`: 4.1.8
- Node: v26.4.0
- OS: macOS 15 (Darwin 25.5.0), Apple Silicon (arm64)

### What steps can we follow to reproduce this issue?

We have a multi-Worker integration test: one primary Worker plus three real auxiliary Workers, each wired via `serviceBindings`, each loaded through `wrangler.unstable_getMiniflareWorkerOptions()` against its own real, already-deployed `wrangler.jsonc` (so bindings — Hyperdrive, KV, Durable Objects, further nested `services` — are real, not invented for the test). All four are real production Cloudflare Workers, individually well-exercised in this pool for years; this is the first time all four run together in one pool instance.

The moment all three auxiliary Workers are wired together alongside the primary, `vitest run --project ` crashes with a raw `Segmentation fault: 11` before any test executes — no JS error, no stack trace, just the process dying.

**Isolation performed (all confirmed live, not assumed):**
- Any TWO of the three auxiliary Workers together (including a circular service-binding pair between two of them) start clean and pass tests.
- Only the full four-Worker graph (primary + all 3 real auxiliaries) crashes.
- NOT about Hyperdrive — crash persists with every `hyperdrives` binding stripped from all four Workers.
- NOT about Durable Objects — crash persists with every `durableObjects` binding stripped too.
- Purely "primary + 3 real named auxiliary Workers through this pool," independent of binding complexity we've tested.
- NOT fixed by upgrading `@cloudflare/vitest-pool-workers` 0.18.8 → 0.19.1 (`miniflare` 4.20260722.0 → 4.20260730.0) — identical crash, identical signature.

**What does NOT reproduce it:** a minimal synthetic reproduction — a trivial primary Worker plus up to 4 trivial auxiliary Workers (each just `export default { fetch() { return new Response(...) } }`), wired with real `serviceBindings` between them, same installed `0.18.8` — starts and serves requests cleanly every time, at every auxiliary count from 1 to 4. So this isn't simply "N auxiliary workers crashes the pool" — something about our real Workers' actual module graphs (larger bundles, `nodejs_compat`, dynamic imports, more binding types, or some combination) is a necessary ingredient we haven't isolated further. Happy to help narrow this down further with guidance on what to try next, or to share a redacted/synthetic repro repo if useful — we didn't want to hold off filing until we had a fully minimal case, since the signature (unconditional segfault, version-independent) seemed worth flagging as-is.

**Confirmed working as a control:** the identical four-Worker configuration (same real bindings, same real service-binding wiring, same Hyperdrive-backed Postgres), constructed with the `miniflare` package directly — bypassing `@cloudflare/vitest-pool-workers` entirely — starts cleanly and correctly proxies a request end-to-end through all four Workers. This rules out the Worker configs themselves, or `workerd`/`miniflare` in general, as the cause — it's specific to something in the pool's own wrapping (its runner worker, the Vite module-transform layer it puts in front of the primary Worker, and/or its inspector/WebSocket control channel).

### What is the actual behavior?

```
*** Received signal #11: Segmentation fault: 11
⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯
Error: [vitest-pool]: Worker cloudflare-pool emitted error.
❯ EventEmitter. .../vitest/dist/chunks/cli-api.*.js
...
Caused by: Error: Worker exited unexpectedly
❯ _WebSocket.emitUnexpectedExit .../vitest/dist/chunks/cli-api.*.js
...
Test Files (1)
Tests no tests
Errors 1 error
```

No test in the file runs — the pool worker process dies during startup/wiring, before any test body executes.

### What is the expected behavior?

Either the pool starts successfully with a real 4-Worker graph (primary + 3 real auxiliary Workers with real bindings), matching the behavior of a raw `Miniflare` instance given the identical configuration — or, if there's a documented/known limit on auxiliary Worker count or complexity for this pool, a clear error message rather than a segfault.

### Additional information

We ended up moving this specific test off `@cloudflare/vitest-pool-workers` onto a raw `Miniflare` instance driven from a plain `node`-pool vitest project (same real bindings, same real service-binding wiring, same runtime) as a working alternative — filing this for visibility/tracking, not because we're blocked, and happy to help debug further if that's useful.

Contributor guide

Open the contributing guide

Research direction

The failure occurs before tests in `vitest run --project `, while the same four-Worker setup works with raw Miniflare. Start by comparing `@cloudflare/vitest-pool-workers`' runner worker, Vite module-transform layer, and inspector/WebSocket control channel against the direct Miniflare path. Done means the graph starts without a segfault and a test executes, or a clear error is reported.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js, typescript
Domain
testing, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.