Provide environment information
System:
OS: Linux 6.17 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
CPU: (6) arm64 unknown
Memory: 14.04 GB / 31.27 GB
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 24.13.1 - /home/main/n/bin/node
npm: 11.8.0 - /home/main/n/bin/npm
pnpm: 10.28.2 - /home/main/.local/share/pnpm/pnpm
SDK version: @trigger.dev/sdk@4.4.3
Describe the bug
When calling task.batchTriggerAndWait(items) with an array of items that include debounce in their options, the debounce is silently ignored. Every item creates a separate run instead of coalescing by debounce key. The TypeScript types accept debounce in per-item options, so there's no compile-time warning.
The same items passed via an async iterable (task.batchTriggerAndWait(asyncGenerator())) correctly apply debounce.
Root cause: In packages/trigger-sdk/src/v3/shared.ts, the batchTriggerAndWait_internal function's array branch (around line 2484) constructs per-item options by explicitly listing fields, and debounce is missing from the list:
lockToVersion,queue,concurrencyKey,test,payloadType,delay,ttl,tags,maxAttempts,metadata,maxDuration,idempotencyKey,idempotencyKeyTTL,idempotencyKeyOptions,machine,priority,region
The streaming transforms (e.g., transformSingleTaskBatchItemsStreamForWait) correctly include debounce: item.options?.debounce.
Reproduction repo
https://github.com/triggerdotdev/trigger.dev/blob/2ba77d8/packages/trigger-sdk/src/v3/shared.ts#L2484-L2510
To reproduce
import{task}from"@trigger.dev/sdk";constmyTask=task({id: "my-task",run: async(payload: {id: string})=>{awaitnewPromise((r)=>setTimeout(r,5000));return{done: true};},});// Parent taskconstparent=task({id: "parent",run: async()=>{// These should coalesce into 1 run per key, but each creates a separate runconstresults=awaitmyTask.batchTriggerAndWait([{payload: {id: "a"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}},{payload: {id: "b"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}},{payload: {id: "c"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}},]);// Expected: 1 run (all 3 debounced to same key)// Actual: 3 separate runsconsole.log("Runs:",results.runs.length);},});Workaround: Use an async iterable instead of an array:
asyncfunction*items(){yield{payload: {id: "a"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}};yield{payload: {id: "b"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}};yield{payload: {id: "c"},options: {debounce: {key: "same-key",delay: "30s",mode: "trailing"}}};}constresults=awaitmyTask.batchTriggerAndWait(items());// Correctly produces 1 runAdditional information
The fix should be a one-line addition in batchTriggerAndWait_internal's array branch — add debounce: item.options?.debounce to the per-item options object, matching what the streaming transforms already do.
Affected paths:
task.batchTriggerAndWait(array) — brokentasks.batchTriggerAndWait(id, array) — broken (same internal function)
Working paths:
task.batchTriggerAndWait(asyncIterable) — worksbatch.triggerAndWait(items) (heterogeneous) — workstask.batchTrigger(array) (fire-and-forget) — works
Provide environment information
System:
OS: Linux 6.17 Ubuntu 24.04.4 LTS 24.04.4 LTS (Noble Numbat)
CPU: (6) arm64 unknown
Memory: 14.04 GB / 31.27 GB
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 24.13.1 - /home/main/n/bin/node
npm: 11.8.0 - /home/main/n/bin/npm
pnpm: 10.28.2 - /home/main/.local/share/pnpm/pnpm
SDK version: @trigger.dev/sdk@4.4.3
Describe the bug
When calling
task.batchTriggerAndWait(items)with an array of items that includedebouncein theiroptions, the debounce is silently ignored. Every item creates a separate run instead of coalescing by debounce key. The TypeScript types acceptdebouncein per-item options, so there's no compile-time warning.The same items passed via an async iterable (
task.batchTriggerAndWait(asyncGenerator())) correctly apply debounce.Root cause: In
packages/trigger-sdk/src/v3/shared.ts, thebatchTriggerAndWait_internalfunction's array branch (around line 2484) constructs per-item options by explicitly listing fields, anddebounceis missing from the list:The streaming transforms (e.g.,
transformSingleTaskBatchItemsStreamForWait) correctly includedebounce: item.options?.debounce.Reproduction repo
https://github.com/triggerdotdev/trigger.dev/blob/2ba77d8/packages/trigger-sdk/src/v3/shared.ts#L2484-L2510
To reproduce
Workaround: Use an async iterable instead of an array:
Additional information
The fix should be a one-line addition in
batchTriggerAndWait_internal's array branch — adddebounce: item.options?.debounceto the per-item options object, matching what the streaming transforms already do.Affected paths:
task.batchTriggerAndWait(array)— brokentasks.batchTriggerAndWait(id, array)— broken (same internal function)Working paths:
task.batchTriggerAndWait(asyncIterable)— worksbatch.triggerAndWait(items)(heterogeneous) — workstask.batchTrigger(array)(fire-and-forget) — works