Skip to content

fix(cloudflare): register container outbound interception with the native Fetcher - #2062

Merged
BlankParticle merged 2 commits into
alchemy-run:mainfrom
apostolos-geyer:fix/container-intercept-fetcher
Oct 6, 2026
Merged

BlankParticle merged 2 commits into
alchemy-run:mainfrom
apostolos-geyer:fix/container-intercept-fetcher

Conversation

@apostolos-geyer

Copy link
Copy Markdown
Contributor

Fixes #2061

interceptOutboundHttp and interceptAllOutboundHttp on a container handle passed workerd a toCloudflareFetcher wrapper, which workerd rejects (parameter 2 is not of type 'Fetcher'). They also returned the rejected promise unawaited as the Effect's value, so the interception never registered and nothing reported it.

 interceptOutboundHttp: (addr: string, binding: Fetcher) =>
-  toCloudflareFetcher(binding).pipe(
-    Effect.map((binding) => state.container!.interceptOutboundHttp(addr, binding)),
-  ),
+  Effect.promise(() => state.container!.interceptOutboundHttp(addr, binding.raw)),

workerd forwards intercepted requests to the binding over RPC, so it needs the native Fetcher, which every Alchemy Fetcher carries as raw. A rejected registration now surfaces as a defect.

LocalContainerIntercept.test.ts covers both methods under alchemy dev: a Durable Object that owns its container through Containers.layer intercepts the container's requests with a stub for its own id. On main both tests fail with getaddrinfo ENOTFOUND.

The open #1905 uses the same toCloudflareFetcher conversion in its new Containers.bind handle, so it needs the same change.

…tive Fetcher

interceptOutboundHttp and interceptAllOutboundHttp converted the binding
with toCloudflareFetcher into a plain { fetch, connect } object, which
workerd rejects ("parameter 2 is not of type 'Fetcher'"), and returned the
rejected promise unawaited as the Effect's value. Pass binding.raw and
await the call so a failure surfaces.

Fixes alchemy-run#2061
@alchemy-version-bot

Copy link
Copy Markdown
Contributor

Install the packages built from this commit:

alchemy

pnpm install https://pkg.alchemy.run/alchemy/pr:2062:7da3561
@alchemy.run (6)
pnpm install https://pkg.alchemy.run/@alchemy.run/better-auth/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@alchemy.run/cloudflare-runtime/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@alchemy.run/frontend-frameworks/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@alchemy.run/node-utils/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@alchemy.run/floci/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@alchemy.run/pkg/pr:2062:7da3561
@distilled.cloud (16)
pnpm install https://pkg.alchemy.run/@distilled.cloud/core/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/acme/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/aws/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/axiom/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/cloudflare/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/doppler/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/fly-io/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/github/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/hetzner/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/infisical/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/neon/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/prisma/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/planetscale/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/railway/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/stripe/pr:2062:7da3561
pnpm install https://pkg.alchemy.run/@distilled.cloud/zerossl/pr:2062:7da3561

Published Oct 6, 2026, 8:06 PM UTC. Expires Oct 13, 2026, 8:06 PM UTC, extended while this pull request is open.

@BlankParticle
BlankParticle merged commit a7dd0b3 into alchemy-run:main Oct 6, 2026
3 of 4 checks passed
BlankParticle added a commit to danieljvdm/alchemy-effect that referenced this pull request Oct 6, 2026
…her in Containers.bind

- Pass `binding.raw` to interceptOutboundHttp, interceptAllOutboundHttp and
  interceptOutboundHttps on the Containers.bind client, matching alchemy-run#2062
- Keep alchemy-run#2062's fix in the Containers.layer handle after the refactor
- Fail Containers.layer monitor() with ContainerError instead of a defect,
  so StartContainer's catchTag("ContainerError") handles crashes
- Cover interception through Containers.bind in the native fixture locally;
  live interception closes the connection with no response (TODO)
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.

Cloudflare Containers: interceptOutboundHttp never registers, and the workerd TypeError is swallowed

2 participants