Summary
A queue producer binding configured with remote: true is silently treated as local in wrangler dev. The user opts in to hitting the deployed remote queue, but messages instead go to Miniflare's in-memory broker. There is no warning, error, or runtime indication that the remote setting was ignored.
Reproduction
// src/index.ts
export default {
async fetch(_req, env) {
await env.MY_QUEUE.send({ hello: "world" });
return new Response("sent");
},
};
Run wrangler dev, hit the worker, then check the deployed my-prod-queue in the Cloudflare dashboard — the message is not there. It went to the local broker.
Expected
One of:
- The message is delivered to the deployed remote queue (matching the user's
remote: true intent), or
wrangler dev rejects remote: true on queue producers at config load (if the design decision is that queues are local-only).
Actual
Silent fallthrough to the local broker. No warning, no error, no log line.
Root cause
The schema accepts remoteProxyConnectionString on queue producers but the plugin never reads it. See packages/miniflare/src/plugins/queues/index.ts:
- Lines 29-33 — schema accepts the field:
remoteProxyConnectionString: z.custom<RemoteProxyConnectionString>().optional()
- Lines 53-135 —
getServices / getBindings never reference it. The binding is unconditionally wired to the local DO-backed broker:
return queues.map<Worker_Binding>(([name, id]) => ({
name,
queue: { name: `${SERVICE_QUEUE_PREFIX}:${id}` },
}));
Compare with packages/miniflare/src/plugins/r2/index.ts:99 (and KV, D1, Workflows, Browser, Images, Stream, Send Email, Pipelines), which all branch on remoteProxyConnectionString and call remoteProxyClientWorker(...) when it's set.
Wrangler's CfQueue type also has remote?: boolean (packages/workers-utils/src/worker.ts:201), and pickRemoteBindings() (packages/wrangler/src/api/remoteBindings/index.ts) DOES include queue producers with remote: true in the remote proxy session — so a session is started for the queue, but Miniflare then ignores the connection string and wires the local broker anyway.
Proposed fixes
Two valid directions, depending on intent:
-
If queues should support remote in dev (which the schema field's presence suggests): wire remoteProxyConnectionString through getServices/getBindings so remote: true proxies the producer to the deployed queue, matching the R2/KV/D1 pattern.
-
If queues are local-only by design: drop remote?: boolean from CfQueue and remoteProxyConnectionString from QueueProducerOptionsSchema so users get a config-level rejection instead of silent local behavior.
Discovery context
Surfaced while consolidating Wrangler's per-binding-type local-development support into a single registry (getBindingLocalSupport). Queue is currently classified as local-and-remote (with a comment noting this issue) to preserve the silent-acceptance behavior; once this is fixed, the classification can be made authoritative.
Summary
A queue producer binding configured with
remote: trueis silently treated as local inwrangler dev. The user opts in to hitting the deployed remote queue, but messages instead go to Miniflare's in-memory broker. There is no warning, error, or runtime indication that the remote setting was ignored.Reproduction
Run
wrangler dev, hit the worker, then check the deployedmy-prod-queuein the Cloudflare dashboard — the message is not there. It went to the local broker.Expected
One of:
remote: trueintent), orwrangler devrejectsremote: trueon queue producers at config load (if the design decision is that queues are local-only).Actual
Silent fallthrough to the local broker. No warning, no error, no log line.
Root cause
The schema accepts
remoteProxyConnectionStringon queue producers but the plugin never reads it. Seepackages/miniflare/src/plugins/queues/index.ts:getServices/getBindingsnever reference it. The binding is unconditionally wired to the local DO-backed broker:Compare with
packages/miniflare/src/plugins/r2/index.ts:99(and KV, D1, Workflows, Browser, Images, Stream, Send Email, Pipelines), which all branch onremoteProxyConnectionStringand callremoteProxyClientWorker(...)when it's set.Wrangler's
CfQueuetype also hasremote?: boolean(packages/workers-utils/src/worker.ts:201), andpickRemoteBindings()(packages/wrangler/src/api/remoteBindings/index.ts) DOES include queue producers withremote: truein the remote proxy session — so a session is started for the queue, but Miniflare then ignores the connection string and wires the local broker anyway.Proposed fixes
Two valid directions, depending on intent:
If queues should support remote in dev (which the schema field's presence suggests): wire
remoteProxyConnectionStringthroughgetServices/getBindingssoremote: trueproxies the producer to the deployed queue, matching the R2/KV/D1 pattern.If queues are local-only by design: drop
remote?: booleanfromCfQueueandremoteProxyConnectionStringfromQueueProducerOptionsSchemaso users get a config-level rejection instead of silent local behavior.Discovery context
Surfaced while consolidating Wrangler's per-binding-type local-development support into a single registry (
getBindingLocalSupport). Queue is currently classified aslocal-and-remote(with a comment noting this issue) to preserve the silent-acceptance behavior; once this is fixed, the classification can be made authoritative.