Skip to content

[miniflare] Verify remote Hyperdrive bindings in local dev (#14900) - #16070

Draft
edmundhung wants to merge 4 commits into
mainfrom
edmundhung/hyperdrive-pr14900-core
Draft

edmundhung wants to merge 4 commits into
mainfrom
edmundhung/hyperdrive-pr14900-core

Conversation

@edmundhung

@edmundhung edmundhung commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Related to #14842 and #14900.

This is a temporary testing ground for remote Hyperdrive support. Please do not merge it; the agreed fixes will go back to #14900.

  • Allow remote: true without a local database connection string.
  • Keep database credentials and queries on the same remote session, shared by Worker and Node clients.
  • Preserve healthy bindings when another binding fails. Retire removed or replaced listeners without interrupting existing connections.
  • Reconnect to the correct database after configuration changes, including changes to the Hyperdrive ID.
  • Exercise real MySQL and PostgreSQL queries through wrangler dev and getPlatformProxy(), plus a direct Miniflare query across reloads.

The long-idle workaround is intentionally excluded.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation

@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8fd130d

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

This PR includes changesets to release 12 packages
Name Type
@cloudflare/config Minor
miniflare Minor
wrangler Minor
@cloudflare/vite-plugin Minor
@cloudflare/vitest-plugin Minor
@cloudflare/autoconfig Patch
@cloudflare/build-output-utils Patch
@cloudflare/containers-shared 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 Oct 5, 2026
@edmundhung edmundhung added the ci:run-remote-tests Run remote/E2E tests that require Cloudflare API credentials label Oct 5, 2026
@ask-bonk

ask-bonk Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

I'm Bonk, and I've done a quick review of your PR.
Adds remote Hyperdrive bindings through Miniflare TCP bridges and edge credential seeding.

  1. High packages/config/src/bindings.ts:256 accepts dev.remote, but packages/config/src/convert.ts:543 drops it when converting cloudflare.config.ts bindings. Those users get a local Hyperdrive binding and are required to supply a local connection string instead of using the remote session.

github run

@pkg-pr-new

pkg-pr-new Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
@cloudflare/autoconfig

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

@cloudflare/build-output-utils

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

@cloudflare/codemods

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

@cloudflare/config

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

@cloudflare/containers-shared

npm i https://pkg.pr.new/@cloudflare/containers-shared@16070

create-cloudflare

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

@cloudflare/deploy-helpers

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

@cloudflare/kv-asset-handler

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

miniflare

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

@cloudflare/pages-functions

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

@cloudflare/pages-shared

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

@cloudflare/runtime-types

npm i https://pkg.pr.new/@cloudflare/runtime-types@16070

@cloudflare/unenv-preset

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

@cloudflare/vite-plugin

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

@cloudflare/vitest-plugin

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

@cloudflare/workers-auth

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

@cloudflare/workers-editor-shared

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

@cloudflare/workers-utils

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

wrangler

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

commit: e694eb9

@edmundhung
edmundhung marked this pull request as ready for review October 5, 2026 18:36
@workers-devprod
workers-devprod requested review from a team and jamesopstad and removed request for a team October 5, 2026 18:37
@workers-devprod

workers-devprod commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/hyperdrive-remote-bindings-local-dev.md: [@cloudflare/wrangler]
  • packages/config/src/tests/convert.test.ts: [@cloudflare/wrangler]
  • packages/config/src/tests/schema.test.ts: [@cloudflare/wrangler]
  • packages/config/src/bindings.ts: [@cloudflare/wrangler]
  • packages/config/src/convert.ts: [@cloudflare/wrangler]
  • packages/config/src/schema.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/config/schema.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/config/v4-convert.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/config/v4-schema.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/hyperdrive/hyperdrive-proxy.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/hyperdrive/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/src/plugins/shared/index.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/config/schema.spec.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/plugins/analytics-sql/index.spec.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/plugins/hyperdrive/index.spec.ts: [@cloudflare/wrangler]
  • packages/miniflare/test/plugins/shared/remote-bindings-connect.spec.ts: [@cloudflare/wrangler]
  • packages/remote-bindings/src/index.ts: [@cloudflare/wrangler]
  • packages/remote-bindings/src/maybe-start-or-update-session.test.ts: [@cloudflare/wrangler]
  • packages/remote-bindings/src/maybe-start-or-update-session.ts: [@cloudflare/wrangler]
  • packages/remote-bindings/src/seed-hyperdrive-bindings.ts: [@cloudflare/wrangler]
  • packages/remote-bindings/templates/remoteBindings/ProxyServerWorker.ts: [@cloudflare/wrangler]
  • packages/vite-plugin-cloudflare/src/miniflare-options.ts: [@cloudflare/wrangler]
  • packages/vitest-plugin/src/pool/config.ts: [@cloudflare/wrangler]
  • packages/vitest-plugin/test/remote-proxy-sessions.test.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/binding-local-support.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/environment.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/config/validation.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/print-bindings.ts: [@cloudflare/wrangler]
  • packages/workers-utils/src/worker.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/miniflare-remote-resources.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/e2e/remote-binding/workers/hyperdrive.js: [@cloudflare/wrangler]
  • packages/wrangler/package.json: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/dev.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/dev/miniflare-hyperdrive.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/integrations/platform/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/LocalRuntimeController.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/api/startDevWorker/MultiworkerRuntimeController.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/dev/miniflare/index.ts: [@cloudflare/wrangler]
  • pnpm-lock.yaml: [@cloudflare/wrangler]

@edmundhung
edmundhung removed the request for review from jamesopstad October 5, 2026 18:37

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 6 potential issues.

Devin Review

Comment thread packages/remote-bindings/src/seed-hyperdrive-bindings.ts Outdated
Comment thread packages/remote-bindings/src/maybe-start-or-update-session.ts Outdated
Comment on lines +346 to +349
this.#teardownServer(`remote:${name}`);
this.#servers.set(`remote:${name}`, server);
this.#remoteBridgePorts.set(name, port);
return port;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Removed Hyperdrive bindings leave bridges running

When a reload removes a remote binding, createRemoteTcpBridge never revisits its key. Its listener and existing database tunnels remain open until Miniflare closes.

Learn more

getServices creates bridges only for bindings still present. Replacing the same key tears down its previous listener, but removing the binding entirely never calls this method for that key. #servers, #connections, and #remoteBridgePorts retain it until full disposal. This also leaves old Node-side binding objects holding a still-usable address after removal.

Example: Start local dev with DB remote, open a pooled database connection, then remove DB from the config and reload. The old bridge keeps accepting connections and the pooled tunnel remains live despite the removed binding.

Recommended fix: Reconcile the controller's active server keys against the full current set of bindings on each configuration update. Tear down absent keys and delete their port entries.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread .changeset/hyperdrive-remote-bindings-local-dev.md Outdated
Comment on lines +315 to +318
const server = net.createServer((clientSocket) => {
this.#trackConnection(`remote:${name}`, clientSocket);
this.#handleRemoteBridgeConnection(clientSocket, wsHref, bindingName);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟥 Unauthenticated local bridge exposes remote database

Any local process can dial createRemoteTcpBridge without authentication. The bridge opens a tunnel to the deployed Hyperdrive database, granting that process database access.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread packages/remote-bindings/templates/remoteBindings/ProxyServerWorker.ts Outdated
@workers-devprod
workers-devprod requested review from a team and NuroDev and removed request for a team October 5, 2026 18:41
@edmundhung
edmundhung marked this pull request as draft October 5, 2026 18:43
mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
`HyperdriveBindingOptions.dev` accepts `remote` (via `BindingDevOptions`),
but `convertToWranglerConfig` only mapped `dev.connectionString` for the
`hyperdrive` case, so the flag was silently dropped. A
`cloudflare.config.ts` user asking for a remote Hyperdrive binding got a
local one instead, and was then required to supply a local connection
string — the exact setup `remote: true` exists to avoid.

The neighbouring `flagship` and `images` cases already map
`dev.remote`; this brings `hyperdrive` in line with them.

Found by Bonk's review on cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
@mack-erel

Copy link
Copy Markdown
Contributor

Thank you for setting this up, @edmundhung — the credentialed run is the one thing I could never get from a fork, since GitHub withholds repository secrets there and the Hyperdrive E2E silently skipped on every green build of #14900. Seeing HYPERDRIVE_MYSQL_DATABASE_URL actually reach the runner here is worth more than all of those.

I've looked at the Windows failure. I think the good news is bigger than the bad news, but there's a real question underneath it that I don't want to paper over.

The functional assertion passed; the equality assertion failed.

The failure is expected false to be true, which is the credential comparison at line 852 — not the query. The MySQL round trip just above it, SELECT 1 AS direct_hyperdrive_probe (line 840, asserted at 842), completed: it authenticated against the real edge and returned 1. So the thing this PR set out to prove — that a database client can authenticate and query through a remote Hyperdrive binding — did get proven, on Windows, four times. The run then failed on the next assertion, and because that threw, the Miniflare-side query below it never ran at all.

Why the equality assertion can't hold.

The test fetches credentials twice: once through seedRemoteHyperdriveBindings(), then again from a separate WebSocket upgrade, and asserts the two match. That isn't a property the design provides. From ProxyServerWorker.ts:145-149:

// Hyperdrive mints per-session credentials and checks them on the socket it
// just opened, so the caller has to present *this* request's values. Handing
// them back on the upgrade response keeps them tied to the connection they
// belong to — fetching them separately can land on a different instance and
// hand out credentials the socket will reject.

Two independent fetches can land on two edge instances and come back with two different credential sets, both valid for their own connection. That the direct probe succeeded with the second set is the evidence: these weren't bad credentials, just different ones. Dropping that assertion and keeping the two query assertions would, I think, leave the test proving exactly what it was written to prove.

The part I'd rather raise than quietly fix.

If two fetches can disagree, the ordinary flow has the same exposure: getPlatformProxy() seeds once from connection A, and every later database connection is a different connection that might land elsewhere. I haven't seen it break — a 14h 38min run on this branch came back clean across 437 probes, and @Ltadrian's manual testing on macOS and Windows passed — but "I haven't seen it" is weaker than "it can't happen," and this test just demonstrated the two fetches disagreeing on the first try. So I'd treat it as an open question for the Hyperdrive team rather than a flaky assertion: is instance affinity within a session something the edge guarantees, or something that happens to hold? If it's the latter, seeding once per session is load-bearing in a way the current design doesn't acknowledge, and I'd want to know that before this ships rather than after.

Bonk's finding was real, and it was mine.

The dev.remote drop in convert.ts is a genuine bug I introduced: I widened HyperdriveBindingOptions.dev to accept remote but never mapped it in the conversion, so a cloudflare.config.ts user asking for a remote binding silently got a local one — and was then required to provide the local connection string that remote: true exists to avoid. The neighbouring flagship and images cases already mapped it; hyperdrive was just missing. Thank you for catching and fixing it here.

I've carried your one-line fix back to #14900 along with your two test cases, and verified both fail without it. #14900 is also now rebased onto current main and back to MERGEABLE — the rebase surfaced two shape changes this branch had to follow (type is no longer a field on a worker's config, and main's new analytics-sql test calls getNodeBindings() with one argument), both fixed there.

Happy to push the E2E assertion change to this branch myself if that's useful, or to leave it to you — whichever fits better with carrying this back.

mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
…ding fails

`seedRemoteHyperdriveBindings()` was awaited inline in the returned
object, so a rejection — a WebSocket error, a missing header, or its
ten-second timeout — threw *after* the session was already live. The
caller never received the handle, leaving no way to dispose the started
proxy: the session leaked for the rest of the process's life.

Disposing it in a catch would be no better. The session is shared with
every other remote binding in the worker, so tearing it down over a
Hyperdrive-only failure would take unrelated service, KV, and R2
bindings with it. Warn and continue with no credentials instead: the
Hyperdrive bindings are degraded for this round, and
`buildMiniflareBindingOptions` already warns again per binding, but the
session stays owned by the caller and usable by everything else. A
reload re-enters this function and retries the seed.

Found by Devin's review on cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
`handleSeedConnectionString` sat in the first branch of the proxy
worker's `fetch`, returning a remote Hyperdrive binding's live
connection string as JSON to any request carrying `MF-HD-Seed` and a
binding name. Nothing authenticated that request beyond reaching the
worker.

It is also dead: credentials moved to the WebSocket upgrade response
(`MF-HD-Connection-String`) precisely because they belong to the
connection that mints them, and `seedRemoteHyperdriveBindings` has read
them from there since. The endpoint was left behind, so it carried the
disclosure risk without being on any path.

Its three tests go with it.

Found by Devin's review on cloudflare#14900; @edmundhung removed the same
endpoint independently in cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
`HyperdriveBindingOptions.dev` accepts `remote` (via `BindingDevOptions`),
but `convertToWranglerConfig` only mapped `dev.connectionString` for the
`hyperdrive` case, so the flag was silently dropped. A
`cloudflare.config.ts` user asking for a remote Hyperdrive binding got a
local one instead, and was then required to supply a local connection
string — the exact setup `remote: true` exists to avoid.

The neighbouring `flagship` and `images` cases already map
`dev.remote`; this brings `hyperdrive` in line with them.

Found by Bonk's review on cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
…ding fails

`seedRemoteHyperdriveBindings()` was awaited inline in the returned
object, so a rejection — a WebSocket error, a missing header, or its
ten-second timeout — threw *after* the session was already live. The
caller never received the handle, leaving no way to dispose the started
proxy: the session leaked for the rest of the process's life.

Disposing it in a catch would be no better. The session is shared with
every other remote binding in the worker, so tearing it down over a
Hyperdrive-only failure would take unrelated service, KV, and R2
bindings with it. Warn and continue with no credentials instead: the
Hyperdrive bindings are degraded for this round, and
`buildMiniflareBindingOptions` already warns again per binding, but the
session stays owned by the caller and usable by everything else. A
reload re-enters this function and retries the seed.

Found by Devin's review on cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
mack-erel added a commit to mack-erel/workers-sdk that referenced this pull request Oct 6, 2026
`handleSeedConnectionString` sat in the first branch of the proxy
worker's `fetch`, returning a remote Hyperdrive binding's live
connection string as JSON to any request carrying `MF-HD-Seed` and a
binding name. Nothing authenticated that request beyond reaching the
worker.

It is also dead: credentials moved to the WebSocket upgrade response
(`MF-HD-Connection-String`) precisely because they belong to the
connection that mints them, and `seedRemoteHyperdriveBindings` has read
them from there since. The endpoint was left behind, so it carried the
disclosure risk without being on any path.

Its three tests go with it.

Found by Devin's review on cloudflare#14900; @edmundhung removed the same
endpoint independently in cloudflare#16070.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LBVk4gda8JuffGPqrR2XKv
@edmundhung
edmundhung force-pushed the edmundhung/hyperdrive-pr14900-core branch 4 times, most recently from 4aaedd7 to 48ac455 Compare October 19, 2026 21:19
@edmundhung
edmundhung force-pushed the edmundhung/hyperdrive-pr14900-core branch 15 times, most recently from 643c159 to ceec2e1 Compare October 20, 2026 10:26
edmundhung and others added 4 commits October 20, 2026 11:51
With remote: true, application code still runs locally and uses an ordinary
database driver, but its connections reach the deployed Hyperdrive binding.
For example, pg.Client can use env.DB.connectionString and run SELECT 1 without
knowing about remote bindings. Miniflare implements this shared path; Wrangler
and Vite only pass through the configuration and resolve local fallbacks.

The local Hyperdrive binding needs a TCP destination, whereas remote bindings
provide remote calls (RPC) and streams over WebSocket. A bridge listening on
127.0.0.1 joins those interfaces without changing the driver or workerd. The
existing local remote-session gateway forwards its WebSocket to a proxy Worker
on Cloudflare, which holds the real Hyperdrive binding. Neither the bridge nor
the proxy interprets SQL: they carry the driver's normal database traffic.

During startup, the bridge opens a persistent RPC session and asks the proxy
Worker for the binding's connection string. Those details configure the local
binding before the local runtime starts. remoteProxyConnectionString names the
gateway URL, not the database URL. When a driver connects, the bridge calls
connect() on the same remote handle and copies bytes between the local socket
and the returned streams. Three driver connections get three independent
database sockets, not one shared database connection.

The shared handle matters because credentials from remote binding instance A
may not authenticate a socket opened by instance B. Fetching a connection
string separately from opening sockets can cross that boundary. One session
owns both operations instead of seeding credentials from a throwaway connection.

- `ProxyServerWorker.ts`: The remote adapter exposes the native binding's
  connection string and a fresh connect() stream pair through the same handle.
- `hyperdrive/index.ts`: Worker bindings route their synthetic database address
  to the TCP bridge. Node bindings instead expose its loopback address and port;
  both receive the session's user, password, and database together.
- `hyperdrive-proxy.ts`: Each remote listener owns its session and accepted clients.
  An unchanged target reuses it. A successful reload retires unused listeners
  without interrupting existing connections; a failed reload rolls back new
  candidates. Shutdown cancels startup and closes active and retired resources.
  The existing local database/TLS proxy remains a separate connection path.
- `remote-affinity.spec.ts`: Different credentials for each simulated session
  make accidental cross-session reuse fail. Worker and Node clients exercise
  reloads, database ID changes, reconnection, and another binding's failure.

Co-authored-by: Henry Jang <jang@hyochan.site>
The existing local TLS proxy can still be waiting for a database greeting or
TLS handshake when its client disconnects. Closing the listener alone does not
close that outbound connection, especially after a reload retires the listener.

Give each accepted client ownership of its outbound TCP, TLS, and fallback
sockets before waiting for them. Client disconnects and shutdown close the
whole connection. A closed peer rejects pending reads and handshake waits, and
cannot trigger a new plaintext fallback after its client has gone away.

PostgreSQL startup bytes may arrive while the proxy waits for the database's
SSL response. Consume a bounded startup buffer so client EOF remains visible,
then replay those bytes in order once TLS or plaintext fallback is ready.

- `proxy.spec.ts`: Controlled pauses at the greeting, SSL response, and TLS
  handshake check cleanup before negotiation completes. Delayed SSL responses
  also check that buffering preserves startup bytes for TLS and fallback paths.

Co-authored-by: Henry Jang <jang@hyochan.site>
Failed startup already tears down its development environment, but a teardown
error can replace the failure the caller needs to diagnose. Preserve the
original error both when startup throws and when it fails before becoming
ready, even if cleanup also rejects.

For a started session, repeated dispose() calls share one teardown promise,
including its rejection. Cleanup is attempted once rather than starting
overlapping teardown operations.

Co-authored-by: Henry Jang <jang@hyochan.site>
A database greeting or a separately fetched connection string does not prove
that the local binding can authenticate through its bridge. Exercise actual
SQL queries against provisioned MySQL and PostgreSQL Hyperdrive resources using
ordinary database drivers. The drivers and PostgreSQL types are test-only
dependencies, not additions to the runtime bundle.

- `hyperdrive-remote.test.ts`: Each protocol runs concurrent queries through
  wrangler dev and a Node-side query through getPlatformProxy(). An invalid
  local connection string confirms remote mode does not use the local fallback.
- `miniflare-remote-resources.test.ts`: A direct Miniflare consumer configures the
  remote binding and runs a MySQL query before and after setOptions(). This
  exercises the shared implementation independently of Wrangler's dev adapter.

Co-authored-by: Henry Jang <jang@hyochan.site>
@edmundhung
edmundhung force-pushed the edmundhung/hyperdrive-pr14900-core branch from ceec2e1 to 8fd130d Compare October 20, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run-remote-tests Run remote/E2E tests that require Cloudflare API credentials

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

3 participants