Repository navigation
[wrangler] Fail with an error instead of hanging under Bun #15846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
petebacondarwin
merged 15 commits into
cloudflare:main
from
oddharsh:oddharsh/bun-harness-keep-getworker
Oct 19, 2026
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
caca08d
Fail early when `createTestHarness()` cannot start its proxy under Bun
dario-piotrowicz 850adad
[wrangler] Keep getWorker() working under Bun and fail only the proxy…
oddharsh 29d0fa7
[wrangler] Fail late retries under a missing control payload, and cov…
oddharsh 4712825
[wrangler] Refuse every harness dispatch under Bun, since #15906 rout…
oddharsh e7ff0ca
Retrigger CI after Windows timeouts in @fixture/entrypoints-rpc and w…
oddharsh 4593180
Merge branch 'main' into oddharsh/bun-harness-keep-getworker
oddharsh f826e0b
Merge remote-tracking branch 'origin/main' into oddharsh/bun-harness-…
oddharsh ab5abe1
[remote-bindings] Fail remote proxy startup under Bun instead of hang…
oddharsh 63eb034
[wrangler] Report the missing control payload to the ProxyWorker dire…
oddharsh 5e8cb23
[remote-bindings] Keep real startup errors under Bun, and confirm pla…
oddharsh e0a5086
[wrangler] Send the missing-payload control request with undici's fetch
oddharsh d3a474e
[remote-bindings] Clear latestSendError on every send so it never des…
oddharsh 27c060e
Retrigger CI after a slow Windows runner timed out @fixture/start-wor…
oddharsh fb3cfe0
Merge branch 'main' into oddharsh/bun-harness-keep-getworker
oddharsh 617272b
[wrangler] Replace Bun delivery tracking with flat isBun() checks
oddharsh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| "wrangler": patch | ||
| "@cloudflare/vite-plugin": patch | ||
| "@cloudflare/vitest-plugin": patch | ||
| --- | ||
|
|
||
| Fail with an error instead of hanging when local dev requests can't work under Bun | ||
|
|
||
| Bun's `fetch()` ignores the undici `dispatcher` that Miniflare routes requests through (oven-sh/bun#39247). Under Bun, `createTestHarness()`'s `server.fetch()` and `server.getWorker()`'s `fetch()`, `email()` and `scheduled()` now throw a `UserError`, requests to the dev server URL get a 503 naming the cause, and starting remote bindings throws a `UserError`. Each of these used to hang with no error. `server.getWorker().getEnv()` and `getExport()` keep working under Bun. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| import { writeFileSync } from "node:fs"; | ||
| import { runInTempDir } from "@cloudflare/workers-utils/test-helpers"; | ||
| import { fetch } from "undici"; | ||
| import { describe, it, vi } from "vitest"; | ||
| import { createTestHarness } from "../../api/test-harness"; | ||
| import { BUN_UNSUPPORTED_MESSAGE } from "../../utils/is-bun"; | ||
| import { mockConsoleMethods } from "../helpers/mock-console"; | ||
|
|
||
| const { isBunMock } = vi.hoisted(() => ({ isBunMock: vi.fn(() => false) })); | ||
| vi.mock("../../utils/is-bun", async (importOriginal) => ({ | ||
| ...(await importOriginal<typeof import("../../utils/is-bun")>()), | ||
| isBun: isBunMock, | ||
| })); | ||
|
|
||
| describe("createTestHarness under Bun", () => { | ||
| mockConsoleMethods(); | ||
| runInTempDir(); | ||
|
|
||
| it("keeps getEnv() working and fails every dispatch with the Bun error", async ({ | ||
| expect, | ||
| onTestFinished, | ||
| }) => { | ||
| isBunMock.mockReturnValue(true); | ||
| onTestFinished(() => { | ||
| isBunMock.mockReturnValue(false); | ||
| }); | ||
|
|
||
| writeFileSync( | ||
| "worker.js", | ||
| `export default { fetch: () => new Response("ok") };` | ||
| ); | ||
| writeFileSync( | ||
| "wrangler.jsonc", | ||
| JSON.stringify({ | ||
| name: "harness-under-bun", | ||
| main: "worker.js", | ||
| compatibility_date: "2026-05-20", | ||
| vars: { PROBE: "yes" }, | ||
| }) | ||
| ); | ||
|
|
||
| const server = createTestHarness({ | ||
| workers: [{ configPath: "./wrangler.jsonc" }], | ||
| }); | ||
| onTestFinished(() => server.close()); | ||
|
|
||
| const { url } = await server.listen(); | ||
|
|
||
| const env = await server.getWorker<{ PROBE: string }>().getEnv(); | ||
| expect(env.PROBE).toBe("yes"); | ||
|
|
||
| const refused = { | ||
| message: expect.stringContaining(BUN_UNSUPPORTED_MESSAGE), | ||
| telemetryMessage: "test harness dispatch under bun", | ||
| }; | ||
| await expect(server.fetch("/")).rejects.toMatchObject(refused); | ||
| await expect(server.getWorker().fetch("/")).rejects.toMatchObject(refused); | ||
| await expect( | ||
| server.getWorker().scheduled({ cron: "* * * * *" }) | ||
| ).rejects.toMatchObject(refused); | ||
|
|
||
| const viaUrl = await fetch(url); | ||
| expect(viaUrl.status).toBe(503); | ||
| expect(await viaUrl.text()).toBe(BUN_UNSUPPORTED_MESSAGE); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| import { describe, it } from "vitest"; | ||
| import { isBun } from "../../utils/is-bun"; | ||
|
|
||
| describe("isBun", () => { | ||
| it("detects whether Bun is the current runtime", ({ expect }) => { | ||
| const originalBunVersion = process.versions.bun; | ||
|
|
||
| try { | ||
| process.versions.bun = undefined; | ||
| expect(isBun()).toBe(false); | ||
|
|
||
| process.versions.bun = "1.4.2"; | ||
| expect(isBun()).toBe(true); | ||
| } finally { | ||
| process.versions.bun = originalBunVersion; | ||
| } | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| /** | ||
| * Returns whether Wrangler is running in the Bun runtime. | ||
| * | ||
| * @returns Whether Wrangler is running in the Bun runtime. | ||
| */ | ||
| export function isBun(): boolean { | ||
| return !!process.versions.bun; | ||
| } | ||
|
|
||
| /** | ||
| * Why requests can't reach the Worker under Bun: Bun's `fetch()` ignores the | ||
| * undici `dispatcher` that Miniflare routes requests and control messages through. | ||
| */ | ||
| export const BUN_UNSUPPORTED_MESSAGE = | ||
| "Wrangler can't forward requests to your Worker under Bun, because Bun's `fetch()` ignores the undici `dispatcher` that Miniflare routes them through (https://github.com/oven-sh/bun/issues/39247). Run this using Node.js."; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.