Skip to content

Conversation

@ericallam
Copy link
Member

@ericallam ericallam commented Dec 17, 2025

Adds support for debounced task runs - when triggering a task with a debounce key, subsequent triggers with the same key will reschedule the existing delayed run instead of creating new runs. This continues until no new triggers occur within the delay window.

Usage

await myTask.trigger({ userId: "123" }, {
  debounce: {
    key: "user-123-update",
    delay: "5s",
    mode: "leading", // default
  }
});
  • key: Scoped to the task identifier
  • delay: How long to wait before executing (supports duration strings like "5s", "1m")
  • mode: Either "leading" or "trailing". Leading debounce will use the payload and options from the first run created with the debounce key. Trailing will use payload and options from the last run.

"trailing" mode overrides

When using mode: "trailing" with debounce, the following options are updated from the last trigger:

  • payload - The task input data
  • metadata - Run metadata
  • tags - Run tags (replaces existing tags)
  • maxAttempts - Maximum retry attempts
  • maxDuration - Maximum compute time
  • machine - Machine preset (cpu/memory)

Behavior

  • First run wins: The first trigger creates the run, subsequent triggers push its execution time later
  • Idempotency keys take precedence: If both are specified, idempotency is checked first
  • Max duration: Configurable via DEBOUNCE_MAX_DURATION_MS env var (default: 10 minutes)

Works with triggerAndWait - parent runs correctly block on the debounced run.

@changeset-bot
Copy link

changeset-bot bot commented Dec 17, 2025

🦋 Changeset detected

Latest commit: 20f3a88

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 26 packages
Name Type
@trigger.dev/sdk Patch
@trigger.dev/python Patch
d3-chat Patch
references-d3-openai-agents Patch
references-nextjs-realtime Patch
references-realtime-hooks-test Patch
references-realtime-streams Patch
references-telemetry Patch
@trigger.dev/build Patch
@trigger.dev/core Patch
@trigger.dev/react-hooks Patch
@trigger.dev/redis-worker Patch
@trigger.dev/rsc Patch
@trigger.dev/schema-to-json Patch
@trigger.dev/database Patch
@trigger.dev/otlp-importer Patch
trigger.dev Patch
@internal/cache Patch
@internal/clickhouse Patch
@internal/redis Patch
@internal/replication Patch
@internal/run-engine Patch
@internal/schedule-engine Patch
@internal/testcontainers Patch
@internal/tracing Patch
@internal/zod-worker Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 17, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This pull request implements debounce support across the stack: database schema and migration adding a JSONB debounce field and DELAYED status; a Redis-backed DebounceSystem with atomic claim/register semantics; RunEngine integration that branches trigger flow for debounce outcomes and registers debounced runs; delayedRun/waitpoint handling for DELAYED runs; API/SDK additions to accept debounce options; propagation of debounce metadata to presenters and UI; new tests and migration docs; and small tool/package tweaks (scripts, typechecks).

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts: complex Redis/Lua logic, atomic claim/register, race-condition handling.
  • internal-packages/run-engine/src/engine/index.ts: trigger flow restructuring, branching for debounce outcomes, integration with debounceSystem and registration semantics.
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts: lock-assisted enqueue, status transitions between DELAYED/RUN_CREATED, enqueue/expire interactions.
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts and related tests: extensive scenario coverage — verify correctness and flakiness/race assumptions.
  • Cross-layer API and typing changes: packages/core schemas, SDK payload threading, RunEngine types, presenter/UI changes — ensure type/serialization consistency.
  • Migration and DB changes: prisma schema and migration SQL — verify migration content matches schema and preserves DB safety.
  • Trace/span changes: traceEvents additions (traceDebouncedRun, stop on span) and runEngine tracing integrations — review lifecycle and duplicate-span avoidance.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ❓ Inconclusive The PR description provides thorough technical documentation of the feature, but it does not follow the repository's required template structure with all specified sections. Add the missing template sections: Closes #, Testing, Changelog, Screenshots, and confirmation of the contributing guide checklist.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(engine): run debounce system' clearly and specifically summarizes the main feature addition - a debounce system for task runs in the engine.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ea-branch-108

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (8)
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx (1)

559-571: Consider displaying debounce creation timestamp and formatting the delay consistently.

The implementation correctly displays the debounce key and delay. However, based on the debounce payload structure ({ key: string; delay: string; createdAt: Date }), the createdAt timestamp is available but not shown. Consider these optional enhancements:

  1. Display createdAt: Similar to how the Idempotency field shows expiration (lines 549-555), displaying when the debounce was created could provide useful context.
  2. Consistent duration formatting: If delay represents a duration, consider using formatDurationMilliseconds (already imported at line 9) for consistency with other duration displays in this file (e.g., line 731-733).

Example enhancement:

 <Property.Item>
   <Property.Label>Debounce</Property.Label>
   <Property.Value>
     {run.debounce ? (
       <div>
         <div className="break-all">Key: {run.debounce.key}</div>
         <div>Delay: {run.debounce.delay}</div>
+        <div>
+          Created: <DateTime date={run.debounce.createdAt} />
+        </div>
       </div>
     ) : (
       "–"
     )}
   </Property.Value>
 </Property.Item>
apps/webapp/app/env.server.ts (1)

614-618: Env schema for maximum debounce duration is consistent

The new RUN_ENGINE_MAXIMUM_DEBOUNCE_DURATION_MS entry is typed and defaulted correctly (1 hour). If you never want to allow non‑positive values, consider adding .positive() to fail fast on bad configuration, but current behavior is acceptable if “0 disables / no cap” is intentional.

packages/trigger-sdk/src/v3/shared.ts (1)

2035-2058: Single-run debounce wiring is correct; consider batch support

Forwarding options?.debounce into triggerTask here correctly exposes debounce for tasks.trigger() and task instance .trigger().

If you intend debounce to work with batch APIs as well (e.g. tasks.batchTrigger, batch.trigger, etc.), you’ll likely want to mirror this by threading debounce through the various batch option mappers (e.g. per‑item options objects in batchTrigger_internal and the transform*BatchItems* helpers) so those paths don’t silently ignore a provided debounce option.

internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (1)

140-168: Consider atomic update with status check to prevent stale updates.

The status update to PENDING at line 145 happens after the enqueue. In a rare race, if the run status changed between the snapshot check (line 107) and this update, the status could be incorrectly overwritten. Consider using a conditional update:

       const updatedRun = await this.$.prisma.taskRun.update({
-        where: { id: runId },
+        where: { 
+          id: runId,
+          status: "DELAYED",
+        },
         data: {
           status: "PENDING",
           queuedAt,
         },
       });

However, since the lock is held throughout the operation, this is likely safe in practice.

apps/webapp/app/presenters/v3/SpanPresenter.server.ts (1)

237-237: Consider using zod for JSON field validation.

The debounce field is a JSON column cast directly. Per coding guidelines for apps/webapp, consider using zod for validation to ensure runtime type safety:

import { z } from "zod";

const DebounceData = z.object({
  key: z.string(),
  delay: z.string(),
  createdAt: z.coerce.date(),
}).nullable();

// Then in getRun:
debounce: DebounceData.parse(run.debounce),

This provides runtime validation and better error messages if the data is malformed.

apps/webapp/app/runEngine/services/triggerTask.server.ts (1)

352-377: Consider adding error handling in the onDebounced callback.

The onDebounced callback creates a traced span but doesn't handle potential errors from traceDebouncedRun. If the tracing fails, the error would propagate and potentially break the debounce flow.

                 onDebounced:
                   body.options?.debounce && body.options?.resumeParentOnCompletion
                     ? async ({ existingRun, waitpoint, debounceKey }) => {
+                        try {
                           return await this.traceEventConcern.traceDebouncedRun(
                             triggerRequest,
                             parentRun?.taskEventStore,
                             {
                               existingRun,
                               debounceKey,
                               incomplete: waitpoint.status === "PENDING",
                               isError: waitpoint.outputIsError,
                             },
                             async (spanEvent) => {
                               const spanId =
                                 options?.parentAsLinkType === "replay"
                                   ? spanEvent.spanId
                                   : spanEvent.traceparent?.spanId
                                   ? `${spanEvent.traceparent.spanId}:${spanEvent.spanId}`
                                   : spanEvent.spanId;
                               return spanId;
                             }
                           );
+                        } catch (error) {
+                          logger.error("Failed to trace debounced run", { error, debounceKey });
+                          return undefined;
+                        }
                       }
                     : undefined,

This ensures tracing failures don't break the debounce functionality.

internal-packages/run-engine/src/engine/tests/debounce.test.ts (1)

1226-1242: Consider adding concurrencyLimitBurstFactor for consistency.

The devEnvironment creation is missing concurrencyLimitBurstFactor which is included in setupAuthenticatedEnvironment. While this likely has a default value, adding it would ensure consistency between test environments.

         data: {
           type: "DEVELOPMENT",
           slug: "dev-slug",
           projectId: prodEnvironment.projectId,
           organizationId: prodEnvironment.organizationId,
           apiKey: "dev_api_key",
           pkApiKey: "dev_pk_api_key",
           shortcode: "dev_short",
           maximumConcurrencyLimit: 10,
+          concurrencyLimitBurstFactor: new Decimal(2.0),
         },

Note: You'll need to import Decimal from the appropriate package.

internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1)

178-179: Consider using setTimeout from timers/promises for consistency.

The current implementation uses a Promise wrapper around setTimeout, but setTimeout from timers/promises is already available and would be more idiomatic.

+import { setTimeout } from "timers/promises";
+
 // In waitForExistingRun:
-await new Promise((resolve) => setTimeout(resolve, CLAIM_RETRY_DELAY_MS));
+await setTimeout(CLAIM_RETRY_DELAY_MS);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff80742 and 96c55cc.

⛔ Files ignored due to path filters (1)
  • references/hello-world/src/trigger/debounce.ts is excluded by !references/**
📒 Files selected for processing (25)
  • .cursor/rules/migrations.mdc (1 hunks)
  • ai/references/migrations.md (1 hunks)
  • apps/webapp/app/env.server.ts (1 hunks)
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts (2 hunks)
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx (1 hunks)
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts (2 hunks)
  • apps/webapp/app/runEngine/services/triggerTask.server.ts (2 hunks)
  • apps/webapp/app/runEngine/types.ts (2 hunks)
  • apps/webapp/app/v3/runEngine.server.ts (1 hunks)
  • apps/webapp/package.json (2 hunks)
  • apps/webapp/test/engine/triggerTask.test.ts (2 hunks)
  • docs/triggering.mdx (1 hunks)
  • internal-packages/database/prisma/migrations/20251216225303_add_debounce_and_delayed_status/migration.sql (1 hunks)
  • internal-packages/database/prisma/schema.prisma (2 hunks)
  • internal-packages/run-engine/src/engine/index.ts (10 hunks)
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1 hunks)
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (3 hunks)
  • internal-packages/run-engine/src/engine/systems/waitpointSystem.ts (1 hunks)
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts (1 hunks)
  • internal-packages/run-engine/src/engine/types.ts (3 hunks)
  • packages/core/src/v3/schemas/api.ts (1 hunks)
  • packages/core/src/v3/schemas/runEngine.ts (1 hunks)
  • packages/core/src/v3/types/tasks.ts (1 hunks)
  • packages/trigger-sdk/package.json (1 hunks)
  • packages/trigger-sdk/src/v3/shared.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • packages/core/src/v3/schemas/api.ts
  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • internal-packages/run-engine/src/engine/types.ts
  • packages/core/src/v3/schemas/runEngine.ts
  • apps/webapp/app/env.server.ts
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/systems/waitpointSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • packages/core/src/v3/schemas/api.ts
  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • packages/core/src/v3/schemas/runEngine.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • packages/core/src/v3/schemas/api.ts
  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • internal-packages/run-engine/src/engine/types.ts
  • packages/core/src/v3/schemas/runEngine.ts
  • apps/webapp/app/env.server.ts
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/systems/waitpointSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/package.json
  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • internal-packages/run-engine/src/engine/types.ts
  • packages/core/src/v3/schemas/runEngine.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/package.json
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • ai/references/migrations.md
  • internal-packages/run-engine/src/engine/systems/waitpointSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • apps/webapp/app/env.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
apps/webapp/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Test files should only import classes and functions from app/**/*.ts files and should not import env.server.ts directly or indirectly; pass configuration through options instead

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Avoid mocks or stubs in tests; use helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for unit tests

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
packages/trigger-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code

Files:

  • packages/trigger-sdk/src/v3/shared.ts
🧠 Learnings (52)
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • apps/webapp/app/presenters/v3/SpanPresenter.server.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • apps/webapp/app/v3/runEngine.server.ts
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • docs/triggering.mdx
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/package.json
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Configure task retry behavior using the `retry` property with options like maxAttempts, factor, and timeout values

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Generate example payloads for tasks when possible

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • docs/triggering.mdx
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to packages/trigger-sdk/**/*.{ts,tsx} : In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: The SDK at packages/trigger-sdk is an isomorphic TypeScript SDK

Applied to files:

  • packages/trigger-sdk/package.json
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : When importing from `trigger.dev/core` in the webapp, use subpath exports from the package.json instead of importing from the root path

Applied to files:

  • packages/trigger-sdk/package.json
  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Set default maximum duration in trigger.config.ts using `maxDuration` property

Applied to files:

  • apps/webapp/app/v3/runEngine.server.ts
  • apps/webapp/app/env.server.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Use the Run Engine 2.0 from `internal/run-engine` for new run lifecycle code in the webapp instead of the legacy run engine

Applied to files:

  • apps/webapp/app/v3/runEngine.server.ts
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.

Applied to files:

  • apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.triggerAndWait()` to trigger a task and wait for its result from a parent task

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Subscribe to run updates using `runs.subscribeToRun()` for realtime monitoring of task execution

Applied to files:

  • apps/webapp/app/runEngine/types.ts
  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `.withStreams()` to subscribe to realtime streams from task metadata in addition to run changes

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Use build extensions in trigger.config.ts (additionalFiles, additionalPackages, aptGet, prismaExtension, etc.) to customize the build

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/package.json
  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure OpenTelemetry instrumentations and exporters in trigger.config.ts for enhanced logging

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/concerns/traceEvents.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use logger methods (debug, log, info, warn, error) from `trigger.dev/sdk/v3` for structured logging in tasks

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Leverage the PostgreSQL database through the `trigger.dev/database` Prisma 6.14.0 client in the webapp for all data access patterns

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • ai/references/migrations.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure global retry settings in trigger.config.ts using `retries` object with defaults for all tasks

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.trigger()` to trigger multiple different tasks at once from backend code

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • docs/triggering.mdx
  • internal-packages/run-engine/src/engine/index.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/app/**/*.{ts,tsx} : Access all environment variables through the `env` export of `env.server.ts` instead of directly accessing `process.env` in the Trigger.dev webapp

Applied to files:

  • apps/webapp/app/env.server.ts
  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Specify runtime environment (node or bun) in trigger.config.ts using the `runtime` property

Applied to files:

  • apps/webapp/app/env.server.ts
📚 Learning: 2025-11-14T16:03:06.917Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2681
File: apps/webapp/app/services/platform.v3.server.ts:258-302
Timestamp: 2025-11-14T16:03:06.917Z
Learning: In `apps/webapp/app/services/platform.v3.server.ts`, the `getDefaultEnvironmentConcurrencyLimit` function intentionally throws an error (rather than falling back to org.maximumConcurrencyLimit) when the billing client returns undefined plan limits. This fail-fast behavior prevents users from receiving more concurrency than their plan entitles them to. The org.maximumConcurrencyLimit fallback is only for self-hosted deployments where no billing client exists.

Applied to files:

  • apps/webapp/app/env.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Control concurrency using the `queue` property with `concurrencyLimit` option

Applied to files:

  • docs/triggering.mdx
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to {packages/core,apps/webapp}/**/*.{ts,tsx} : Use zod for validation in packages/core and apps/webapp

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-26T14:40:07.146Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2710
File: packages/schema-to-json/package.json:0-0
Timestamp: 2025-11-26T14:40:07.146Z
Learning: Node.js 24+ has native TypeScript support and can execute .ts files directly without tsx or ts-node for scripts that use only erasable TypeScript syntax (type annotations, interfaces, etc.). The trigger.dev repository uses Node.js 24.11.1+ and scripts like updateVersion.ts can be run with `node` instead of `tsx`.

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: The webapp at apps/webapp is a Remix 2.1 application using Node.js v20

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use vitest for unit tests

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use vitest for all tests in the Trigger.dev repository

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • apps/webapp/package.json
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure build process in trigger.config.ts using `build` object with external packages, extensions, and JSX settings

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: pnpm version `10.23.0` and Node.js version `20.11.1` are required for development

Applied to files:

  • apps/webapp/package.json
📚 Learning: 2025-07-12T18:06:04.133Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.

Applied to files:

  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to internal-packages/database/**/*.{ts,tsx} : Use Prisma for database interactions in internal-packages/database with PostgreSQL

Applied to files:

  • ai/references/migrations.md
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schedules.task()` for scheduled/cron tasks instead of regular `task()`

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTask()` to batch trigger tasks by passing task instances for static task sets

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `runs.subscribeToBatch()` to subscribe to changes for all runs in a batch

Applied to files:

  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.trigger()` to trigger a task from inside another task with specified payload

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-10-08T11:48:12.327Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2593
File: packages/core/src/v3/workers/warmStartClient.ts:168-170
Timestamp: 2025-10-08T11:48:12.327Z
Learning: The trigger.dev runners execute only in Node 21 and 22 environments, so modern Node.js APIs like AbortSignal.any (introduced in v20.3.0) are supported.

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
🧬 Code graph analysis (7)
apps/webapp/app/v3/runEngine.server.ts (2)
apps/webapp/app/env.server.ts (1)
  • env (1285-1285)
apps/supervisor/src/env.ts (1)
  • env (119-119)
internal-packages/run-engine/src/engine/types.ts (2)
internal-packages/redis/src/index.ts (1)
  • RedisOptions (4-4)
packages/core/src/v3/schemas/common.ts (2)
  • TaskRun (209-234)
  • TaskRun (236-236)
internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (1)
internal-packages/run-engine/src/engine/systems/executionSnapshotSystem.ts (1)
  • getLatestExecutionSnapshot (95-113)
internal-packages/run-engine/src/engine/index.ts (1)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1)
  • DebounceSystem (59-542)
apps/webapp/test/engine/triggerTask.test.ts (1)
apps/webapp/app/runEngine/types.ts (2)
  • TriggerTaskRequest (24-30)
  • TracedEventSpan (124-140)
internal-packages/run-engine/src/engine/tests/debounce.test.ts (4)
internal-packages/testcontainers/src/index.ts (1)
  • containerTest (233-241)
internal-packages/run-engine/src/engine/tests/setup.ts (2)
  • setupAuthenticatedEnvironment (21-82)
  • setupBackgroundWorker (84-293)
apps/webapp/app/v3/runEngine.server.ts (2)
  • engine (11-11)
  • RunEngine (13-13)
internal-packages/run-engine/src/engine/index.ts (1)
  • RunEngine (76-2055)
apps/webapp/app/runEngine/concerns/traceEvents.server.ts (1)
apps/webapp/app/runEngine/types.ts (1)
  • TracedEventSpan (124-140)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (36)
packages/trigger-sdk/package.json (1)

131-131: LGTM!

Formatting change adds trailing newline, following standard conventions. No functional impact.

apps/webapp/package.json (1)

17-17: LGTM!

Memory boost for TypeScript compilation is appropriate given the expanded codebase with debounce features. The cross-env wrapper ensures cross-platform compatibility.

packages/core/src/v3/schemas/runEngine.ts (1)

16-16: LGTM!

The DELAYED status is correctly added to TaskRunExecutionStatus and aligns with the Prisma schema enum addition. Type constraints are satisfied.

internal-packages/database/prisma/schema.prisma (2)

584-586: LGTM!

The debounce JSON field is properly documented and appropriately nullable for backward compatibility. This aligns with the migration and broader debounce feature implementation.


954-955: LGTM!

The DELAYED enum variant is well-positioned in the execution status flow and clearly documented. This matches the migration and supports the debounce workflow.

packages/core/src/v3/types/tasks.ts (1)

899-932: LGTM!

The debounce option is well-documented with clear examples and explanations. The type structure is straightforward and consistent with other trigger options. The scoping behavior is clearly explained.

packages/core/src/v3/schemas/api.ts (1)

206-211: LGTM!

The debounce field in the API schema correctly matches the TypeScript type definition in tasks.ts. The structure is consistent and properly optional.

ai/references/migrations.md (1)

1-121: LGTM!

Excellent documentation of the Prisma migration workflow. The step-by-step instructions clearly explain the cleanup process for extraneous edits, and the example perfectly matches the actual migration in this PR.

internal-packages/database/prisma/migrations/20251216225303_add_debounce_and_delayed_status/migration.sql (1)

1-5: LGTM!

Clean migration that precisely matches the Prisma schema changes. The use of JSONB for the debounce column is appropriate for storing structured debounce options. This follows the workflow documented in migrations.md.

internal-packages/run-engine/src/engine/systems/waitpointSystem.ts (1)

579-590: Correctly skipping DELAYED runs in waitpoint continuation

Treating DELAYED like other non-progressing states here (debug + status: "skipped") is the right behavior so waitpoint completion doesn’t prematurely resume delayed runs.

apps/webapp/app/v3/runEngine.server.ts (1)

185-188: RunEngine debounce configuration wiring looks correct

maxDebounceDurationMs is plumbed from the validated env and matches the new RunEngineOptions["debounce"] shape; no issues here.

.cursor/rules/migrations.mdc (1)

1-6: Migration rules doc looks good

Front‑matter and the pointer to ai/references/migrations.md are clear and consistent with other rule files.

docs/triggering.mdx (1)

834-893: Debounce documentation is clear and aligned with the feature design

The section accurately describes debounce semantics (task‑scoped keys, first‑payload wins, DELAYED runs, triggerAndWait behavior, and idempotency precedence) and includes solid examples.

internal-packages/run-engine/src/engine/types.ts (1)

10-11: Engine debounce options and callback typing look sound

The new debounce block on RunEngineOptions and the debounce/onDebounced fields on TriggerParams are well‑typed and consistent with the debounce flow (using TaskRun/Waitpoint for the callback). This should integrate cleanly with the new DebounceSystem and tracing hooks.

Also applies to: 86-90, 172-185

packages/trigger-sdk/src/v3/shared.ts (1)

2269-2290: triggerAndWait debounce propagation matches trigger()

Including debounce: options?.debounce in the triggerAndWait_internal request keeps the semantics between trigger() and triggerAndWait() aligned and enables the debounced wait behavior described in the docs.

apps/webapp/app/runEngine/types.ts (2)

134-140: Span API extension for debounced runs is reasonable

Adding stop(): void to TracedEventSpan gives the trigger path a clean way to end the original span when a debounced run is reused, without forcing an event write. This matches the intended debounce tracing behavior.


159-169: traceDebouncedRun hook completes the tracing surface

The new traceDebouncedRun method mirrors traceIdempotentRun and exposes the right context (existingRun, debounceKey, status flags) for debounced runs, which should make implementing debounced tracing straightforward.

apps/webapp/test/engine/triggerTask.test.ts (1)

69-137: LGTM! Mock implementations correctly extended for debounce support.

The MockTraceEventConcern class properly implements all three tracing methods with the new stop binding and the new traceDebouncedRun method. The mock signature matches the TraceEventConcern interface.

internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (1)

100-138: Lock coordination with skipRunLock prevents deadlock.

The refactored enqueueDelayedRun correctly acquires the run lock first, then passes skipRunLock: true to enqueueRun to avoid deadlock since the outer lock is already held. The status check before enqueue properly handles race conditions with debounce rescheduling.

apps/webapp/app/presenters/v3/SpanPresenter.server.ts (1)

361-362: Debounce field correctly added to selection set.

The selection set update properly includes the debounce field for retrieval.

apps/webapp/app/runEngine/concerns/traceEvents.server.ts (2)

54-54: LGTM! Stop binding correctly added to span objects.

The stop: event.stop.bind(event) binding is correctly added to both traceRun and traceIdempotentRun, matching the updated TracedEventSpan type definition.

Also applies to: 120-120


128-192: LGTM! Well-structured debounced tracing implementation.

The traceDebouncedRun method correctly mirrors the idempotent run tracing pattern with appropriate debounce-specific messaging. The icon choice and attribute setup are consistent with existing patterns.

Note: There is structural similarity with traceIdempotentRun. If additional similar tracing methods are added in the future, consider extracting a shared helper to reduce duplication.

apps/webapp/app/runEngine/services/triggerTask.server.ts (2)

163-176: LGTM! Debounce delay validation is well-structured.

The delay parsing correctly falls back from explicit delay to debounce.delay, and the validation properly enforces that debounce requires a valid delay duration. Error messages are informative and include the provided values.


382-386: LGTM! Proper span lifecycle management for debounced runs.

The logic correctly stops the outer span when the run was debounced (detected by differing friendlyId), preventing duplicate trace events since the debounced span is created separately via onDebounced.

internal-packages/run-engine/src/engine/tests/debounce.test.ts (1)

11-96: LGTM!

Comprehensive test for basic debounce creation. Properly verifies the DELAYED status, debounce metadata storage in DB, and execution snapshot status.

internal-packages/run-engine/src/engine/systems/debounceSystem.ts (4)

10-48: LGTM!

Type definitions are well-structured. Uses types over interfaces as per coding guidelines, and the discriminated union for DebounceResult is a good pattern for handling the three possible outcomes.


102-158: LGTM!

The atomic claim implementation using SET NX PX is correct for distributed coordination. The handling of the "pending" state (another server creating) and the edge case where the key expires between SET and GET is well-implemented.


357-435: LGTM!

The handleDebounce method correctly orchestrates the distributed debounce flow with atomic claiming, waiting for pending claims, and handling existing runs. Good use of tracing for observability.


445-515: LGTM!

The registration method correctly verifies claim ownership before overwriting, preventing race conditions where the claim expired and another server took over. Good use of TTL with buffer.

internal-packages/run-engine/src/engine/index.ts (7)

50-50: LGTM!

Import is correctly placed with other system imports.


302-308: LGTM!

DebounceSystem initialization correctly uses shared resources, falls back to runLock.redis if debounce-specific Redis config isn't provided, and sets a sensible default max debounce duration of 1 hour.


452-506: LGTM!

The debounce handling in the trigger method correctly handles all three outcomes:

  • existing: Returns the existing run and blocks parent if needed for triggerAndWait
  • max_duration_exceeded: Continues to create a new run with attribute set for observability
  • new: Stores claimId for later registration

The onDebounced callback integration for creating trace spans is well-designed.


579-590: LGTM!

Debounce metadata is correctly stored with the run, including createdAt for tracking max duration. The execution snapshot status correctly distinguishes between DELAYED and RUN_CREATED.


660-680: LGTM!

The debounce registration correctly happens after the run is created and delay is scheduled. The warning log for a lost claim is appropriate, and continuing despite registration failure is acceptable since the run already exists.


1406-1408: LGTM!

DebounceSystem Redis connection is properly closed during engine shutdown.


1882-1884: LGTM!

The DELAYED status is correctly handled:

  • Heartbeat handler throws NotImplementedError since delayed runs shouldn't be heartbeating
  • Repair handler returns early since delayed runs don't need repair

Both are consistent with the behavior for RUN_CREATED.

Also applies to: 1925-1926

@vibe-kanban-cloud
Copy link

Vibe Kanban Review Complete

Your code review is ready!

View Review

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/cli-v3/src/build/manifests.ts (1)

55-58: Verify necessity of the Uint8Array cast.

The explicit cast to Uint8Array may be unnecessary since readFile returns a Buffer, which already extends Uint8Array and is compatible with createHash().update() (accepts BinaryLike). Consider investigating whether this cast is working around a type resolution issue that could be fixed at the root cause.

If the cast is needed due to TypeScript version or configuration constraints, consider adding a comment explaining why it's necessary.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96c55cc and 57f45f1.

⛔ Files ignored due to path filters (1)
  • references/hello-world/src/trigger/debounce.ts is excluded by !references/**
📒 Files selected for processing (7)
  • .changeset/ninety-cows-lay.md (1 hunks)
  • packages/cli-v3/src/build/manifests.ts (1 hunks)
  • packages/cli-v3/src/entryPoints/dev-run-controller.ts (1 hunks)
  • packages/cli-v3/src/entryPoints/managed/execution.ts (1 hunks)
  • packages/core/src/v3/schemas/api.ts (2 hunks)
  • packages/core/src/v3/zodSocket.ts (1 hunks)
  • packages/trigger-sdk/src/v3/shared.ts (12 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/core/src/v3/zodSocket.ts
  • .changeset/ninety-cows-lay.md
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • packages/cli-v3/src/entryPoints/dev-run-controller.ts
  • packages/cli-v3/src/entryPoints/managed/execution.ts
  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/cli-v3/src/build/manifests.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • packages/cli-v3/src/entryPoints/dev-run-controller.ts
  • packages/cli-v3/src/entryPoints/managed/execution.ts
  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/cli-v3/src/build/manifests.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • packages/cli-v3/src/entryPoints/dev-run-controller.ts
  • packages/cli-v3/src/entryPoints/managed/execution.ts
  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
  • packages/cli-v3/src/build/manifests.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • packages/core/src/v3/schemas/api.ts
packages/trigger-sdk/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code

Files:

  • packages/trigger-sdk/src/v3/shared.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions

Applied to files:

  • packages/core/src/v3/schemas/api.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • packages/core/src/v3/schemas/api.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • packages/core/src/v3/schemas/api.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • packages/core/src/v3/schemas/api.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTask()` to batch trigger tasks by passing task instances for static task sets

Applied to files:

  • packages/core/src/v3/schemas/api.ts
  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.trigger()` to trigger multiple different tasks at once from backend code

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • packages/trigger-sdk/src/v3/shared.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
packages/cli-v3/src/entryPoints/managed/execution.ts (1)

375-384: LGTM! Correct handling of the new DELAYED status.

The addition of DELAYED as an invalid execution status alongside RUN_CREATED is correct. Both represent pre-execution states (initial creation and delayed/debounced waiting), so encountering them during active execution processing indicates an error condition that should abort the execution. The fall-through pattern appropriately shares the same handling logic.

packages/cli-v3/src/entryPoints/dev-run-controller.ts (1)

429-435: LGTM! Correct handling of new DELAYED status.

The addition of the DELAYED case (along with QUEUED) to the switch statement is appropriate for the dev environment. Since delayed runs are waiting for the debounce delay to elapse, no action is needed in the dev controller until they transition to EXECUTING. The fall-through behavior is consistent with other statuses that don't require immediate handling, and the assertExhaustive call ensures type safety.

packages/trigger-sdk/src/v3/shared.ts (1)

652-652: LGTM! Debounce field properly threaded through all trigger paths.

The debounce option is consistently propagated through all batch trigger variants (by ID and by task), streaming transforms, and internal trigger functions. The use of optional chaining (?.) is appropriate since debounce is an optional feature.

Also applies to: 908-908, 1168-1168, 1429-1429, 1765-1765, 1817-1817, 1868-1868, 1919-1919, 1972-1972, 2025-2025, 2067-2067, 2299-2299

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
internal-packages/run-engine/src/engine/tests/delays.test.ts (1)

76-79: Consider checking both run.status and executionData.snapshot.executionStatus for consistency.

The TTL test (line 260) and cancelling test (line 363) verify both the returned run.status and the fetched executionData.snapshot.executionStatus are DELAYED. For consistency and thoroughness, consider adding the run.status check to these assertions as well.

Example for lines 76-79:

 //should be delayed but not queued yet
 const executionData = await engine.getRunExecutionData({ runId: run.id });
 assertNonNullable(executionData);
 expect(executionData.snapshot.executionStatus).toBe("DELAYED");
+expect(run.status).toBe("DELAYED");

Apply similar changes at lines 158-161 and 173-176.

Also applies to: 158-161, 173-176

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57f45f1 and 96680f0.

📒 Files selected for processing (1)
  • internal-packages/run-engine/src/engine/tests/delays.test.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Avoid mocks or stubs in tests; use helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for unit tests

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
📚 Learning: 2025-07-12T18:06:04.133Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.

Applied to files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
🧬 Code graph analysis (1)
internal-packages/run-engine/src/engine/tests/delays.test.ts (2)
apps/webapp/app/v3/runEngine.server.ts (1)
  • engine (11-11)
internal-packages/testcontainers/src/utils.ts (1)
  • assertNonNullable (173-176)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
internal-packages/run-engine/src/engine/tests/delays.test.ts (1)

76-79: LGTM! Test expectations correctly updated to reflect the new DELAYED status.

The changes properly update all delay-related test expectations from the legacy RUN_CREATED status to the new DELAYED status, aligning with the PR's introduction of a dedicated DELAYED execution state. The tests continue to provide comprehensive coverage of delay scenarios including basic delays, rescheduling, TTL expiration, and cancellation.

Also applies to: 158-161, 173-176, 256-260, 359-363

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1)

294-300: Verify that parseNaturalLanguageDuration supports millisecond durations.

Tests use millisecond delay values like "300ms" and "500ms", but a previous review noted that parseNaturalLanguageDuration may only support w/d/hr/h/m/s units. If millisecond durations are not supported, the tests and user-provided debounce delays with "ms" suffix will fail or be treated as invalid.

Please run the following script to verify millisecond support in parseNaturalLanguageDuration:

#!/bin/bash
# Check the implementation of parseNaturalLanguageDuration to verify supported time units
rg -n "parseNaturalLanguageDuration" packages/core/src/v3/isomorphic -A 30 | head -80
internal-packages/run-engine/src/engine/tests/debounce.test.ts (1)

1-8: Missing vi import from vitest.

The vi global is used on line 8 but not imported. Add vi to the import statement.

Apply this diff:

-import { expect } from "vitest";
+import { expect, vi } from "vitest";
🧹 Nitpick comments (1)
packages/core/src/v3/types/tasks.ts (1)

900-936: Well-structured debounce option with comprehensive documentation.

The type definition is clean and follows existing patterns in TriggerOptions. The inline documentation is excellent, with clear examples and constraint details.

Optional documentation enhancements:

Consider documenting the behavior when both the top-level delay option (line 797) and debounce.delay are specified. Additionally, the PR summary mentions that "idempotency is checked first" when both idempotencyKey and debounce are provided—clarifying this precedence in the JSDoc could help users understand the interaction.

Verify zod schema validation:

Ensure that corresponding zod schema validation exists in packages/core/src/v3/schemas/api.ts for:

  • The delay field format validation (duration string pattern)
  • The key field max length constraint (512 characters)
  • The minimum delay value (1 second)

Based on coding guidelines for packages/core.

#!/bin/bash
# Description: Verify zod schema validation for the debounce field exists

# Search for debounce schema definitions in the schemas directory
echo "=== Searching for debounce schema definitions ==="
rg -n -C5 'debounce' packages/core/src/v3/schemas/api.ts

echo ""
echo "=== Checking for delay string validation ==="
rg -n -C3 'z\.(string|object).*delay' packages/core/src/v3/schemas/

echo ""
echo "=== Checking for key length validation ==="
rg -n -C3 '(max|length).*512' packages/core/src/v3/schemas/
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96680f0 and f048420.

⛔ Files ignored due to path filters (1)
  • references/hello-world/src/trigger/debounce.ts is excluded by !references/**
📒 Files selected for processing (4)
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1 hunks)
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts (1 hunks)
  • packages/core/src/v3/schemas/api.ts (2 hunks)
  • packages/core/src/v3/types/tasks.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/v3/schemas/api.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • packages/core/src/v3/types/tasks.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Avoid mocks or stubs in tests; use helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for unit tests

Files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
🧠 Learnings (27)
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.triggerAndWait()` to trigger a task and wait for its result from a parent task

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Configure task retry behavior using the `retry` property with options like maxAttempts, factor, and timeout values

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions

Applied to files:

  • packages/core/src/v3/types/tasks.ts
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Use vitest for unit tests

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:26:37.432Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T16:26:37.432Z
Learning: Applies to **/*.{test,spec}.{ts,tsx} : Use vitest for all tests in the Trigger.dev repository

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocks or stubs in tests; use helpers from `internal/testcontainers` when Redis or Postgres are needed

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.test.{ts,tsx} : Test files should only import classes and functions from `app/**/*.ts` files and should not import `env.server.ts` directly or indirectly; pass configuration through options instead

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Test files should live beside the files under test and use descriptive `describe` and `it` blocks

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-10-08T11:48:12.327Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2593
File: packages/core/src/v3/workers/warmStartClient.ts:168-170
Timestamp: 2025-10-08T11:48:12.327Z
Learning: The trigger.dev runners execute only in Node 21 and 22 environments, so modern Node.js APIs like AbortSignal.any (introduced in v20.3.0) are supported.

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-07-12T18:06:04.133Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Subscribe to run updates using `runs.subscribeToRun()` for realtime monitoring of task execution

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Control concurrency using the `queue` property with `concurrencyLimit` option

Applied to files:

  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Canceled delayed runs can still enqueue

Delayed runs now start with executionStatus set to DELAYED instead of the legacy RUN_CREATED. Some run-cancel logic relies on “initial state” checks that only match RUN_CREATED to call preventDelayedRunFromBeingEnqueued, so canceling a delayed run can leave the scheduled enqueueDelayedRun job active and enqueue the run anyway later.

internal-packages/run-engine/src/engine/index.ts#L507-L606

const status = delayUntil ? "DELAYED" : "PENDING";
//create run
let taskRun: TaskRun & { associatedWaitpoint: Waitpoint | null };
const taskRunId = RunId.fromFriendlyId(friendlyId);
try {
taskRun = await prisma.taskRun.create({
include: {
associatedWaitpoint: true,
},
data: {
id: taskRunId,
engine: "V2",
status,
friendlyId,
runtimeEnvironmentId: environment.id,
environmentType: environment.type,
organizationId: environment.organization.id,
projectId: environment.project.id,
idempotencyKey,
idempotencyKeyExpiresAt,
taskIdentifier,
payload,
payloadType,
context,
traceContext,
traceId,
spanId,
parentSpanId,
lockedToVersionId,
taskVersion,
sdkVersion,
cliVersion,
concurrencyKey,
queue,
lockedQueueId,
workerQueue,
isTest,
delayUntil,
queuedAt,
maxAttempts,
taskEventStore,
priorityMs,
queueTimestamp: queueTimestamp ?? delayUntil ?? new Date(),
ttl,
tags:
tags.length === 0
? undefined
: {
connect: tags,
},
runTags: tags.length === 0 ? undefined : tags.map((tag) => tag.name),
oneTimeUseToken,
parentTaskRunId,
rootTaskRunId,
replayedFromTaskRunFriendlyId,
batchId: batch?.id,
resumeParentOnCompletion,
depth,
metadata,
metadataType,
seedMetadata,
seedMetadataType,
maxDurationInSeconds,
machinePreset: machine,
scheduleId,
scheduleInstanceId,
createdAt,
bulkActionGroupIds: bulkActionId ? [bulkActionId] : undefined,
planType,
realtimeStreamsVersion,
debounce: debounce
? {
key: debounce.key,
delay: debounce.delay,
createdAt: new Date(),
}
: undefined,
executionSnapshots: {
create: {
engine: "V2",
executionStatus: delayUntil ? "DELAYED" : "RUN_CREATED",
description: delayUntil ? "Run is delayed" : "Run was created",
runStatus: status,
environmentId: environment.id,
environmentType: environment.type,
projectId: environment.project.id,
organizationId: environment.organization.id,
workerId,
runnerId,
},
},
associatedWaitpoint: {
create: this.waitpointSystem.buildRunAssociatedWaitpoint({
projectId: environment.project.id,
environmentId: environment.id,
}),
},
},

Fix in Cursor Fix in Web


Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b115627 and 3bbee8c.

⛔ Files ignored due to path filters (1)
  • references/hello-world/src/trigger/debounce.ts is excluded by !references/**
📒 Files selected for processing (10)
  • apps/webapp/app/runEngine/services/triggerTask.server.ts (2 hunks)
  • docs/triggering.mdx (1 hunks)
  • internal-packages/run-engine/src/engine/index.ts (10 hunks)
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1 hunks)
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (3 hunks)
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts (1 hunks)
  • internal-packages/run-engine/src/engine/tests/delays.test.ts (6 hunks)
  • internal-packages/run-engine/src/engine/types.ts (3 hunks)
  • packages/core/src/v3/schemas/api.ts (2 hunks)
  • packages/core/src/v3/types/tasks.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/core/src/v3/schemas/api.ts
  • docs/triggering.mdx
  • packages/core/src/v3/types/tasks.ts
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/tests/delays.test.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/tests/delays.test.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/tests/delays.test.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Avoid mocks or stubs in tests; use helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for unit tests

Files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
🧠 Learnings (29)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Subscribe to run updates using `runs.subscribeToRun()` for realtime monitoring of task execution

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `.withStreams()` to subscribe to realtime streams from task metadata in addition to run changes

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Configure task retry behavior using the `retry` property with options like maxAttempts, factor, and timeout values

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use logger methods (debug, log, info, warn, error) from `trigger.dev/sdk/v3` for structured logging in tasks

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Leverage the PostgreSQL database through the `trigger.dev/database` Prisma 6.14.0 client in the webapp for all data access patterns

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure global retry settings in trigger.config.ts using `retries` object with defaults for all tasks

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.trigger()` to trigger multiple different tasks at once from backend code

Applied to files:

  • internal-packages/run-engine/src/engine/types.ts
  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-07-12T18:06:04.133Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.

Applied to files:

  • internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts
  • internal-packages/run-engine/src/engine/tests/delays.test.ts
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • internal-packages/run-engine/src/engine/tests/delays.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `runs.subscribeToBatch()` to subscribe to changes for all runs in a batch

Applied to files:

  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Configure OpenTelemetry instrumentations and exporters in trigger.config.ts for enhanced logging

Applied to files:

  • internal-packages/run-engine/src/engine/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.triggerAndWait()` to trigger a task and wait for its result from a parent task

Applied to files:

  • internal-packages/run-engine/src/engine/index.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schedules.task()` for scheduled/cron tasks instead of regular `task()`

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use lifecycle functions (init, cleanup, onStart, onSuccess, onFailure, handleError) for task event handling

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
🧬 Code graph analysis (4)
internal-packages/run-engine/src/engine/types.ts (2)
internal-packages/redis/src/index.ts (1)
  • RedisOptions (4-4)
packages/core/src/v3/schemas/common.ts (2)
  • TaskRun (209-234)
  • TaskRun (236-236)
internal-packages/run-engine/src/engine/index.ts (1)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1)
  • DebounceSystem (77-741)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (5)
internal-packages/run-engine/src/engine/systems/systems.ts (1)
  • SystemResources (10-20)
internal-packages/redis/src/index.ts (3)
  • Redis (4-4)
  • RedisCommander (4-4)
  • Callback (4-4)
internal-packages/run-engine/src/engine/systems/executionSnapshotSystem.ts (1)
  • getLatestExecutionSnapshot (95-113)
internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (1)
  • DelayedRunSystem (14-213)
packages/core/src/v3/isomorphic/duration.ts (1)
  • parseNaturalLanguageDuration (1-68)
apps/webapp/app/runEngine/services/triggerTask.server.ts (4)
packages/core/src/v3/tryCatch.ts (1)
  • tryCatch (8-15)
apps/webapp/app/utils/delays.ts (1)
  • parseDelay (17-42)
internal-packages/run-engine/src/engine/errors.ts (1)
  • ServiceValidationError (69-78)
apps/webapp/app/v3/services/common.server.ts (1)
  • ServiceValidationError (1-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (28)
internal-packages/run-engine/src/engine/types.ts (2)

86-90: LGTM!

The debounce configuration options are well-structured with optional Redis config and a configurable max duration. The inline documentation is helpful.


172-186: LGTM!

The debounce and onDebounced additions to TriggerParams are properly typed. Good use of string union for mode ("leading" | "trailing") instead of an enum, per coding guidelines. The JSDoc clearly explains the callback's purpose.

internal-packages/run-engine/src/engine/tests/delays.test.ts (2)

76-79: LGTM!

The expectation update from RUN_CREATED to DELAYED correctly reflects the new execution status for delayed runs.


405-509: Good test coverage for the race condition fix.

This test effectively validates the scenario where delayUntil is updated (e.g., by debounce reschedule) while the worker job is about to fire. The approach of directly updating the database to simulate the race is appropriate for this edge case.

One minor note: the comment on lines 502-504 clarifies why the test doesn't verify eventual QUEUED state, which is helpful for understanding the test's scope.

internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (3)

43-49: LGTM!

Correctly checks for both DELAYED (new status) and RUN_CREATED (legacy) to maintain backwards compatibility with existing delayed runs.


103-145: The race condition fix is properly implemented.

The previous review flagged that enqueue could occur at the original time even when delayUntil was rescheduled. This is now addressed with:

  1. Lock acquisition (line 105) to synchronize with reschedule operations
  2. Status check (lines 110-116) ensuring run is still delayed
  3. Critical fix: delayUntil > now check (lines 136-145) that skips enqueue if the delay was pushed forward

This correctly prevents the race where the worker job fires while debounce is rescheduling.


149-154: Correct use of skipRunLock to avoid deadlock.

Since this function already holds the lock from line 105, passing skipRunLock: true to enqueueRun prevents a nested lock acquisition attempt that would cause a deadlock.

apps/webapp/app/runEngine/services/triggerTask.server.ts (3)

163-176: LGTM!

The delay source derivation correctly prioritizes body.options?.delay over body.options?.debounce?.delay, and the validation at lines 172-176 ensures debounce always has a valid delay duration before proceeding.


352-377: LGTM!

The onDebounced callback is correctly set only when both debounce and resumeParentOnCompletion are specified. The callback properly creates a debounced span via traceDebouncedRun and computes the appropriate spanId based on replay or external traceparent context.


382-392: Trace span handling for debounced runs is now correct.

The previous review flagged that debounced triggers could lose their trace span. This is now fixed:

  • For triggerAndWait (with resumeParentOnCompletion): the outer span is stopped (line 391) because a replacement span was created via onDebounced
  • For regular trigger: the condition on lines 388-389 ensures event.stop() is NOT called, so the span completes normally

This preserves tracing for both debounce modes.

internal-packages/run-engine/src/engine/systems/debounceSystem.ts (8)

1-102: LGTM!

Well-structured module with clear type definitions. The DebounceOptions, DebounceResult, and DebounceData types properly represent the debounce state machine. The class constructor correctly sets up the Redis client with appropriate key prefix and error handling.


104-124: Good use of Lua script for atomic conditional deletion.

The conditionallyDeletePendingKey Lua script addresses the race condition flagged in previous reviews. It atomically checks if the value starts with pending: before deleting, preventing the scenario where a valid run ID is deleted after the original server completes.


172-228: LGTM!

The claimDebounceKey method correctly implements atomic claiming via SET NX. The return type clearly distinguishes between: claimed successfully, existing run ID found, or pending state (another server creating). Good debug logging throughout.


288-324: Race condition fix is properly implemented.

The previous review flagged that unconditional DEL after timeout could delete a valid run ID if the original server completed between the last check and deletion. This is now fixed by using conditionallyDeletePendingKey (line 298) which only deletes if the value is still in pending state.


417-428: Good fix for the "reschedule can move earlier" issue.

The previous review flagged that a shorter debounce.delay on subsequent triggers could move the run earlier instead of always pushing later. This is now correctly handled by comparing newDelayUntil > currentDelayUntil before calling rescheduleDelayedRun. The rescheduling is skipped if the new delay wouldn't actually push the execution time later.


596-612: Good claim verification before registration.

The check at line 599 ensures we still own the pending claim before overwriting with the run ID. This prevents the race where our claim expired and another server took over while we were creating the run. Returning false allows the caller to handle this gracefully.


673-736: LGTM!

The #updateRunForTrailingMode helper correctly updates run data for trailing-mode debounce, including payload, metadata, tags, and execution limits. The tag update uses Prisma's set operation to replace existing tags atomically.


743-755: LGTM!

The module augmentation correctly extends the RedisCommander interface to include the custom Lua command. The JSDoc documents the return value semantics.

internal-packages/run-engine/src/engine/index.ts (10)

50-50: LGTM!

The DebounceSystem import and public property declaration follow the same pattern as other systems in RunEngine.

Also applies to: 99-99


441-442: LGTM!

The addition of debounce and onDebounced parameters to TriggerParams appropriately extends the trigger API to support debounced runs.


452-521: LGTM!

The debounce handling logic properly covers all three result statuses (existing, new, max_duration_exceeded) with appropriate early returns, parent blocking for triggerAndWait, and claim tracking for distributed race protection.


594-600: LGTM!

The debounce metadata (key, delay, createdAt) is properly persisted in the TaskRun for tracking and debugging purposes.


604-604: LGTM!

The change from RUN_CREATED to DELAYED execution status for delayed runs improves clarity. The PR summary confirms backwards compatibility is maintained for existing delayed runs.


669-695: Good edge case handling for lost debounce claim.

The registration logic properly handles the case where the claim is lost between creation and registration by logging a warning without failing the trigger operation. This is appropriate since the run has already been created and scheduled.


1421-1423: LGTM!

The debounce system cleanup is properly integrated into the quit() method to ensure Redis connections are closed during shutdown.


1897-1899: LGTM!

The DELAYED status handling in heartbeat stall is correct and consistent with RUN_CREATED. Delayed runs should not have active heartbeats since they're not executing.


1940-1941: LGTM!

The DELAYED status is appropriately grouped with other non-repairable states in the repair snapshot handler, as delayed runs will be automatically enqueued by the scheduled worker job.


302-308: The default max debounce duration of 1 hour is correct and consistent across the codebase. The type definition explicitly documents this default, and the implementation correctly uses 60 * 60 * 1000 milliseconds. No changes needed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (2)

16-31: Add validation for minimum debounce delay.

The DebounceOptions.delay field accepts any string, but based on learnings, millisecond delays are not supported and the minimum delay is 1 second. Consider adding validation or documentation to enforce this constraint, especially since parseNaturalLanguageDuration only supports w/d/hr/h/m/s units.

💡 Consider adding validation

Add a validation helper to enforce the minimum delay:

function validateDebounceDelay(delay: string): { valid: true; delay: string } | { valid: false; error: string } {
  const parsed = parseNaturalLanguageDuration(delay);
  if (!parsed) {
    return { valid: false, error: "Invalid delay format. Supported units: w, d, hr, h, m, s (minimum 1s)" };
  }
  const delayMs = parsed.getTime() - Date.now();
  if (delayMs < 1000) {
    return { valid: false, error: "Minimum debounce delay is 1 second" };
  }
  return { valid: true, delay };
}

Based on learnings, millisecond delays are not supported and the minimum delay is 1 second.


508-521: Consider deleting Redis key for consistency.

When parseNaturalLanguageDuration returns undefined, the code calls claimKeyForNewRun without first deleting the Redis key. All other error paths in this method (lines 459, 476, 499, 537) delete the Redis key before calling claimKeyForNewRun. While claimKeyForNewRun will handle the existing key by waiting or claiming, explicit deletion would be more consistent and clear.

🔎 Apply this diff for consistency
 const newDelayUntil = parseNaturalLanguageDuration(debounce.delay);
 if (!newDelayUntil) {
   this.$.logger.error("handleExistingRun: invalid delay duration", {
     delay: debounce.delay,
   });
-  // Invalid delay but we still need to atomically claim before returning "new"
+  // Clean up stale Redis key and atomically claim before returning "new"
+  await this.redis.del(redisKey);
   return await this.claimKeyForNewRun({
     environmentId,
     taskIdentifier,
     debounce,
     tx,
   });
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d3bc3c and d78877b.

📒 Files selected for processing (2)
  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts (1 hunks)
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal-packages/run-engine/src/engine/tests/debounce.test.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions
📚 Learning: 2025-12-18T14:09:01.965Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2794
File: internal-packages/run-engine/src/engine/systems/debounceSystem.ts:390-397
Timestamp: 2025-12-18T14:09:01.965Z
Learning: In internal-packages/run-engine/src/engine/systems/debounceSystem.ts, do not allow debounce delays shorter than 1 second. The parseNaturalLanguageDuration function currently supports only weeks, days, hours, minutes, and seconds (w/d/hr/h/m/s). Millisecond delays are not supported. Update any input validation, error messages, and related tests to reflect a minimum 1s debounce and restrict inputs to the supported units.

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-07-12T18:06:04.133Z
Learnt from: matt-aitken
Repo: triggerdotdev/trigger.dev PR: 2264
File: apps/webapp/app/services/runsRepository.server.ts:172-174
Timestamp: 2025-07-12T18:06:04.133Z
Learning: In apps/webapp/app/services/runsRepository.server.ts, the in-memory status filtering after fetching runs from Prisma is intentionally used as a workaround for ClickHouse data delays. This approach is acceptable because the result set is limited to a maximum of 100 runs due to pagination, making the performance impact negligible.

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Subscribe to run updates using `runs.subscribeToRun()` for realtime monitoring of task execution

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger.config.ts : Set default maximum duration in trigger.config.ts using `maxDuration` property

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Scope idempotency keys globally or to current run using the scope parameter

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
📚 Learning: 2025-10-08T11:48:12.327Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2593
File: packages/core/src/v3/workers/warmStartClient.ts:168-170
Timestamp: 2025-10-08T11:48:12.327Z
Learning: The trigger.dev runners execute only in Node 21 and 22 environments, so modern Node.js APIs like AbortSignal.any (introduced in v20.3.0) are supported.

Applied to files:

  • internal-packages/run-engine/src/engine/systems/debounceSystem.ts
🧬 Code graph analysis (1)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (4)
internal-packages/run-engine/src/engine/systems/systems.ts (1)
  • SystemResources (10-20)
internal-packages/run-engine/src/engine/systems/executionSnapshotSystem.ts (1)
  • getLatestExecutionSnapshot (95-113)
internal-packages/run-engine/src/engine/systems/delayedRunSystem.ts (1)
  • DelayedRunSystem (14-213)
packages/core/src/v3/isomorphic/duration.ts (1)
  • parseNaturalLanguageDuration (1-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (11)
internal-packages/run-engine/src/engine/systems/debounceSystem.ts (11)

84-102: LGTM!

The constructor properly initializes all dependencies and sets up Redis with appropriate error handling. The key prefix approach avoids index requirements by scoping keys in Redis.


104-140: LGTM!

The Lua scripts correctly implement atomic operations to prevent TOCTOU race conditions. The conditionallyDeletePendingKey ensures we don't delete valid run IDs, and registerIfClaimOwned ensures we don't overwrite another server's registration.


142-177: LGTM!

The helper methods properly encapsulate key generation and atomic deletion. The fallback to deleted: true when result is undefined is a safe default.


188-244: LGTM!

The atomic claim operation using SET NX correctly prevents duplicate run creation. The distinction between pending state (another server creating) and registered run ID (existing run found) enables proper coordination.


254-312: LGTM!

This method correctly addresses the race condition by ensuring atomic key claiming before returning "new" status. The claimId is always provided, preventing unsafe plain SET operations during registration.


319-423: LGTM!

The timeout handling correctly uses conditionallyDeletePendingKey (atomic Lua script) to prevent the race condition where a valid run ID could be deleted. All exit paths properly handle the found run or atomically claim before returning "new".


541-576: LGTM!

The reschedule logic correctly ensures debounce always "pushes later" by checking newDelayUntil > currentDelayUntil. This addresses the past review concern about potentially moving runs earlier.


611-691: LGTM!

The main handleDebounce method properly coordinates the claim-based flow and ensures a claimId is always provided when returning "new" status. The tracing spans provide good observability.


784-870: LGTM!

The clearDebounceKey and #updateRunForTrailingMode methods correctly handle their respective operations. The conditional field updates in trailing mode properly handle optional fields.


872-906: LGTM!

The module augmentation correctly declares the custom Redis commands with appropriate types. The quit method properly cleans up the Redis connection.


701-779: The atomic registerIfClaimOwned Lua script correctly prevents the TOCTOU race condition.

All code paths returning { status: "new" } (lines 283 and 653) include a claimId, and the only production caller in engine/index.ts always passes the claim ID. Lua scripts execute atomically, ensuring no other Redis commands run concurrently during script execution, which eliminates the race between claim verification and registration. The plain SET fallback (when claimId is absent) is defensive code that shouldn't be reached in normal operation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d78877b and 20f3a88.

📒 Files selected for processing (2)
  • apps/webapp/app/runEngine/services/triggerTask.server.ts (2 hunks)
  • apps/webapp/test/engine/triggerTask.test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use vitest for all tests in the Trigger.dev repository

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
apps/webapp/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Test files should only import classes and functions from app/**/*.ts files and should not import env.server.ts directly or indirectly; pass configuration through options instead

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx,js,jsx}: Test files should live beside the files under test and use descriptive describe and it blocks
Avoid mocks or stubs in tests; use helpers from @internal/testcontainers when Redis or Postgres are needed
Use vitest for unit tests

Files:

  • apps/webapp/test/engine/triggerTask.test.ts
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
🧠 Learnings (22)
📓 Common learnings
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2794
File: internal-packages/run-engine/src/engine/systems/debounceSystem.ts:390-397
Timestamp: 2025-12-18T14:09:01.965Z
Learning: In the debounce system (internal-packages/run-engine/src/engine/systems/debounceSystem.ts), millisecond delays are not supported. The minimum debounce delay is 1 second (1s). The parseNaturalLanguageDuration function supports w/d/hr/h/m/s units only.
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Subscribe to run updates using `runs.subscribeToRun()` for realtime monitoring of task execution

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use metadata methods (set, del, replace, append, remove, increment, decrement, stream, flush) to update metadata during task execution

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.triggerAndWait()` to trigger a task and wait for its result from a parent task

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTriggerAndWait()` to batch trigger tasks and wait for all results from a parent task

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `batch.triggerAndWait()` to batch trigger multiple different tasks and wait for results

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:48.109Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T16:27:48.109Z
Learning: Applies to **/*.test.{ts,tsx,js,jsx} : Avoid mocks or stubs in tests; use helpers from `internal/testcontainers` when Redis or Postgres are needed

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-12-18T14:09:01.965Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2794
File: internal-packages/run-engine/src/engine/systems/debounceSystem.ts:390-397
Timestamp: 2025-12-18T14:09:01.965Z
Learning: In the debounce system (internal-packages/run-engine/src/engine/systems/debounceSystem.ts), millisecond delays are not supported. The minimum debounce delay is 1 second (1s). The parseNaturalLanguageDuration function supports w/d/hr/h/m/s units only.

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:26:44.496Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/executing-commands.mdc:0-0
Timestamp: 2025-11-27T16:26:44.496Z
Learning: For running tests, navigate into the package directory and run `pnpm run test --run` to enable single-file test execution (e.g., `pnpm run test ./src/engine/tests/ttl.test.ts --run`)

Applied to files:

  • apps/webapp/test/engine/triggerTask.test.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schedules.task()` for scheduled/cron tasks instead of regular `task()`

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `schemaTask()` from `trigger.dev/sdk/v3` with Zod schema for payload validation

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use lifecycle functions (init, cleanup, onStart, onSuccess, onFailure, handleError) for task event handling

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-10-08T11:48:12.327Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 2593
File: packages/core/src/v3/workers/warmStartClient.ts:168-170
Timestamp: 2025-10-08T11:48:12.327Z
Learning: The trigger.dev runners execute only in Node 21 and 22 environments, so modern Node.js APIs like AbortSignal.any (introduced in v20.3.0) are supported.

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
🧬 Code graph analysis (1)
apps/webapp/test/engine/triggerTask.test.ts (2)
apps/webapp/app/runEngine/types.ts (1)
  • TracedEventSpan (124-140)
apps/webapp/app/runEngine/services/triggerTask.server.ts (1)
  • RunEngineTriggerTaskService (51-494)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/webapp/app/runEngine/services/triggerTask.server.ts (1)

163-191: Debounce delay validation correctly addresses past review concern.

The separate validation of debounce.delay (lines 179-190) ensures that even when an explicit delay is valid, the debounce.delay is also validated. This prevents silent failures during reschedule operations and correctly addresses the past review comment about missing validation.

apps/webapp/test/engine/triggerTask.test.ts (3)

83-83: LGTM: Mock span implementations updated correctly.

The addition of stop: () => {} to mock spans aligns with the updated TracedEventSpan interface and supports the new debounce tracing flow.

Also applies to: 108-109, 133-133


114-137: LGTM: traceDebouncedRun mock implementation follows expected pattern.

The mock correctly mirrors the structure of traceIdempotentRun and provides the necessary test scaffolding for debounced run tracing.


941-1174: LGTM: Comprehensive test coverage for debounce delay validation.

The three new tests correctly verify:

  1. Rejection of invalid formats when no explicit delay is provided (e.g., "300ms")
  2. Rejection of invalid debounce.delay even when explicit delay is valid
  3. Acceptance of valid formats (e.g., "5s")

This directly tests the validation logic that addresses the past review concern about missing debounce delay validation.

Based on learnings, the minimum debounce delay is 1 second with supported formats: w/d/hr/h/m/s.

@ericallam ericallam merged commit 3875bb2 into main Dec 18, 2025
16 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants