Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion alchemy/src/cloudflare/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,14 @@ async function provisionResources<B extends Bindings>(
input.eventSources
? Promise.all(
input.eventSources.map(async (eventSource) => {
return await QueueConsumer(`${eventSource.queue.id}-consumer`, {
// In local dev mode, queue.id is "" (no Cloudflare API call).
// Use queue.dev.id (resource ID, e.g. "email-queue") to avoid
// all consumers colliding on the same "-consumer" resource ID.
// See: https://github.com/alchemy-run/alchemy/issues/1363
const queueConsumerId = options.local
? eventSource.queue.dev?.id || eventSource.queue.id
Copy link
Collaborator

Choose a reason for hiding this comment

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

wouldn't we want this the other way around?

const queueConsumerId = options.local
              ? eventSource.queue.id ?? eventSource.queue.dev?.id
              : eventSource.queue.id;

or if we know that the non-dev queue id is always going to be bad just

const queueConsumerId = options.local
              ? eventSource.queue.dev?.id
              : eventSource.queue.id;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The || is intentional here. In local dev mode, queue.id is "" (empty string, not null/undefined) because no Cloudflare API call is made to create the real queue.

  • ?? (suggestion 1) would NOT fall back on "" since nullish coalescing only triggers on null/undefined — the bug would remain (all consumers collide on "-consumer").
  • Only dev?.id (suggestion 2) would work but loses the safety fallback if dev is somehow not set.

|| treats "" as falsy → falls back to dev.id → each consumer gets a unique resource ID like "email-queue-consumer". This is the correct behavior.

: eventSource.queue.id;
return await QueueConsumer(`${queueConsumerId}-consumer`, {
queue: eventSource.queue,
scriptName: options.name,
settings: eventSource.settings,
Expand Down
Loading