cloudflare / cloudflare/workers-sdk

Queue producer bindings silently ignore `remote: true` in `wrangler dev`

Open
#13,727 4 comments 0 reactions 2 assignees Claimed by @MattieTK View on GitHub
feature:remote-bindings package:miniflare product:queues
Dominant language
TypeScript
Stars
4.5k
Forks
1.5k
Avg merge
3d 8h
Merged PRs (30d)
187

Description

## 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

```jsonc
// wrangler.json
{
"queues": {
"producers": [
{ "binding": "MY_QUEUE", "queue": "my-prod-queue", "remote": true }
]
}
}
```

```ts
// 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:
```ts
remoteProxyConnectionString: z.custom().optional()
```
- Lines 53-135 — `getServices` / `getBindings` never reference it. The binding is unconditionally wired to the local DO-backed broker:
```ts
return queues.map(([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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.