Skip to content

Queue producer bindings silently ignore remote: true in wrangler dev #13727

@penalosa

Description

@penalosa

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

// wrangler.json
{
  "queues": {
    "producers": [
      { "binding": "MY_QUEUE", "queue": "my-prod-queue", "remote": true }
    ]
  }
}
// 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:

  1. 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.

  2. 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.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions