Skip to content

[miniflare] Lazily initialize remote binding RPC sessions - #15432

Open
razethion wants to merge 2 commits into
cloudflare:mainfrom
razethion:fix/lazy-remote-binding-rpc-sessions
Open

[miniflare] Lazily initialize remote binding RPC sessions#15432
razethion wants to merge 2 commits into
cloudflare:mainfrom
razethion:fix/lazy-remote-binding-rpc-sessions

Conversation

@razethion

@razethion razethion commented Aug 30, 2026

Copy link
Copy Markdown

Fixes #15351.

Remote bindings use two paths through Miniflare's shared proxy client:

  • fetch() requests use HTTP.
  • RPC method calls use a WebSocket RPC session through Cap'n Web.

The proxy client previously created the RPC session eagerly in its constructor. This happened even for fetch-only bindings such as D1 and R2. Their successful requests continued through HTTP, while the unused RPC session could fail later and emit delayed internal error; reference = ... messages.

This change creates and caches the RPC session only when an RPC method is called. Fetch-only bindings therefore no longer open an unrelated WebSocket connection. RPC bindings continue to use one shared session when needed.

Investigation

RPC support for remote bindings was introduced in #10249. The intended design was to keep methods implemented by the proxy worker, particularly fetch(), on their direct path and forward other methods through an RPC stub. The original review discussion notes that direct fetch requests were intentionally kept outside JSRPC because that path is more efficient.

However, the fallback RPC stub was created before the proxy knew whether it would be used. #10724 later replaced the original JSRPC implementation with Cap'n Web while preserving this eager session lifecycle.

Simply delaying initialization until an unknown property is accessed is not sufficient because workerd probes optional WorkerEntrypoint handlers during startup. The proxy now returns a deferred method for unknown properties and initializes the RPC session only if that method is invoked.

This explains why affected D1 requests still returned 200: the request used the HTTP path successfully, while the separate unused RPC session produced the delayed errors.

Validation

The new Miniflare tests verify that:

  • A fetch-only remote binding makes its HTTP request without opening an RPC WebSocket.
  • Calling a real RPC method opens one WebSocket session and returns the expected result.

A packaged alpha build was also installed in the affected application and tested with the original remote D1 reproduction. The delayed internal-error flood no longer occurred.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: This fixes internal remote-binding proxy behavior without changing the public API or configuration.

Devin Review

@changeset-bot

changeset-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7c17adf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@cloudflare/vite-plugin Patch
@cloudflare/vitest-plugin Patch
miniflare Patch
wrangler Patch
@cloudflare/deploy-helpers Patch
@cloudflare/pages-shared Patch
@cloudflare/remote-bindings Patch
@cloudflare/runtime-types Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk Aug 30, 2026
@workers-devprod
workers-devprod requested review from a team and dario-piotrowicz and removed request for a team August 30, 2026 18:24
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/clean-dodos-travel.md: [@cloudflare/wrangler]
  • packages/miniflare/src/workers/shared/remote-proxy-client.worker.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/plugins/shared/remote-bindings-proxy-client.spec.ts: [@cloudflare/wrangler]

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Aug 30, 2026

Copy link
Copy Markdown
@cloudflare/autoconfig

npm i https://pkg.pr.new/@cloudflare/autoconfig@15432

@cloudflare/build-output-utils

npm i https://pkg.pr.new/@cloudflare/build-output-utils@15432

@cloudflare/codemods

npm i https://pkg.pr.new/@cloudflare/codemods@15432

@cloudflare/config

npm i https://pkg.pr.new/@cloudflare/config@15432

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@15432

@cloudflare/deploy-helpers

npm i https://pkg.pr.new/@cloudflare/deploy-helpers@15432

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@15432

miniflare

npm i https://pkg.pr.new/miniflare@15432

@cloudflare/pages-functions

npm i https://pkg.pr.new/@cloudflare/pages-functions@15432

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@15432

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@15432

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@15432

@cloudflare/vitest-plugin

npm i https://pkg.pr.new/@cloudflare/vitest-plugin@15432

@cloudflare/workers-auth

npm i https://pkg.pr.new/@cloudflare/workers-auth@15432

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@15432

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@15432

wrangler

npm i https://pkg.pr.new/wrangler@15432

commit: 7c17adf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

wrangler dev remote D1 logs "internal error; reference =" in clusters of 3 while D1 execute still returns 200

2 participants