{"record":{"id":"4b20612c2785b3e6","repo":"anomalyco/sst","slug":"cannot-subscribe-to-the-this-constructorname-4b2061","errorCode":null,"errorMessage":"Cannot subscribe to the \"${this.constructorName}\" queue multiple times. A Cloudflare Queue can only have one consumer.","messagePattern":"Cannot subscribe to the \"(.+?)\" queue multiple times\\. A Cloudflare Queue can only have one consumer\\.","errorType":"validation","errorClass":"VisibleError","httpStatus":null,"severity":"error","filePath":"platform/src/components/cloudflare/queue.ts","lineNumber":249,"sourceCode":"   *\n   * Configure batch settings.\n   *\n   * ```ts title=\"sst.config.ts\"\n   * queue.subscribe(\"consumer.ts\", {\n   *   batch: {\n   *     size: 10,\n   *     window: \"20 seconds\",\n   *   },\n   * });\n   * ```\n   */\n  public subscribe(\n    subscriber: Input<string | WorkerArgs>,\n    args?: QueueSubscribeArgs,\n    opts?: ComponentResourceOptions,\n  ) {\n    if (this.isSubscribed) {\n      throw new VisibleError(\n        `Cannot subscribe to the \"${this.constructorName}\" queue multiple times. A Cloudflare Queue can only have one consumer.`,\n      );\n    }\n\n    this.isSubscribed = true;\n\n    const parent = this;\n    const name = this.constructorName;\n\n    return new QueueWorkerSubscriber(\n      `${name}Subscriber`,\n      {\n        queue: { id: this.queue.id },\n        subscriber,\n        accountId: this.constructorArgs?.accountId,\n        dlq: this.constructorArgs?.dlq,\n        maxConcurrency: this.constructorArgs?.maxConcurrency,\n        batch: args?.batch,","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/cloudflare/queue.ts#L231-L267","documentation":"SST throws this when `subscribe()` is called more than once on a `sst.cloudflare.Queue`. Cloudflare Queues support at most one consumer per queue, so a second subscription would produce an invalid resource. SST tracks subscription state with `isSubscribed` and fails fast at synth time with a VisibleError.","triggerScenarios":"Calling `queue.subscribe(...)` a second time on the same Queue component, e.g. wiring two workers to consume the same queue, or a shared component module that subscribes on import being used twice.","commonSituations":"Teams adding a second consumer worker to an existing queue; re-exported component wrappers whose module side effects run subscribe again; copy-pasted infra code reusing a queue variable in two stacks/components.","solutions":["Keep a single `subscribe()` call; move the extra consuming logic into the same subscribed worker","Create a separate Cloudflare Queue for the second consumer and produce to both queues","Use Cloudflare's dead-letter or fan-out patterns (e.g. a worker that re-publishes) instead of multiple direct consumers"],"exampleFix":"// before\nqueue.subscribe(workerA);\nqueue.subscribe(workerB); // throws\n// after\nqueue.subscribe(workerA);\nconst queueB = new sst.cloudflare.Queue('QueueB');\nworkerA.addHandler('fanout', async () => { /* send to queueB */ });\nqueueB.subscribe(workerB);","handlingStrategy":"validation","validationCode":"if (subscribedQueues.has(queue.node.id)) throw new Error(`Queue ${queue.node.id} already subscribed`);\nsubscribedQueues.add(queue.node.id);\nqueue.subscribe(worker);","typeGuard":null,"tryCatchPattern":"// VisibleError throws at synth time, not runtime\ntry { queue.subscribe(workerA); } catch (e) { console.error('Queue already has a consumer:', e.message); }","preventionTips":["Subscribe each Cloudflare Queue exactly once, in one place","Encapsulate queue creation + subscribe in a single component function","Use separate queues for additional consumers","Track subscriptions in a module-level set when multiple modules may subscribe"],"tags":["cloudflare","queues","configuration","duplicate-consumer"],"backgroundTag":"queue-consumer-already-set","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}