Skip to content

fix: downgrade queue size limit errors to warnings#3243

Open
ericallam wants to merge 2 commits intomainfrom
feature/tri-7911-downgrade-queue-size-limit-errors-to-warnings
Open

fix: downgrade queue size limit errors to warnings#3243
ericallam wants to merge 2 commits intomainfrom
feature/tri-7911-downgrade-queue-size-limit-errors-to-warnings

Conversation

@ericallam
Copy link
Member

Queue limit ServiceValidationErrors were being logged at error level. These are
expected validation rejections, not bugs.

  • Add logLevel property to ServiceValidationError (webapp + run-engine)
  • Set logLevel: warn on all queue limit throws
  • Schedule engine: detect queue limit failures and log as warn
  • Redis-worker: respect logLevel on thrown errors

Queue limit ServiceValidationErrors were being logged at error level,
consuming ~1.37M Sentry events/week (66% of total budget). These are
expected validation rejections, not bugs.

- Add logLevel property to ServiceValidationError (webapp + run-engine)
- Set logLevel: warn on all queue limit throws
- Schedule engine: detect queue limit failures and log as warn
- Redis-worker: respect logLevel on thrown errors

refs TRI-7911
@changeset-bot
Copy link

changeset-bot bot commented Mar 21, 2026

⚠️ No Changeset found

Latest commit: b1b6aa3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f1224621-a3d7-4732-bacc-ec1010e9072c

📥 Commits

Reviewing files that changed from the base of the PR and between 969973c and b1b6aa3.

📒 Files selected for processing (1)
  • internal-packages/run-engine/src/run-queue/index.ts
✅ Files skipped from review due to trivial changes (1)
  • internal-packages/run-engine/src/run-queue/index.ts
📜 Recent review details
⏰ 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). (28)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 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 (5, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: sdk-compat / Deno Runtime
  • GitHub Check: typecheck / typecheck
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: Analyze (javascript-typescript)

Walkthrough

Added a ServiceValidationErrorLevel type and extended ServiceValidationError constructors to accept a logLevel. Several places that throw queue-size errors now pass "warn" as the log level. The schedule engine callback return type gained an optional errorType ("QUEUE_LIMIT" | "SYSTEM_ERROR"), and handlers classify queue-limit failures to record different metrics and emit warnings instead of errors. The worker's error logging was changed to use the error's logLevel to determine severity. Some run-queue logging calls were downgraded from info to debug.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete; it lacks the required Checklist section, Testing section details, and Changelog section from the template. Complete the PR description by adding the Checklist section (mark completed items), describe testing steps in the Testing section, and add a short changelog summary.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: downgrading queue size limit errors from error to warning level logging.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/tri-7911-downgrade-queue-size-limit-errors-to-warnings

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

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment on lines 74 to 82
export class ServiceValidationError extends Error {
constructor(
message: string,
public status?: number,
public metadata?: Record<string, unknown>
public metadata?: Record<string, unknown>,
public logLevel?: ServiceValidationErrorLevel
) {
super(message);
this.name = "ServiceValidationError";
Copy link
Contributor

Choose a reason for hiding this comment

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

🚩 Divergent ServiceValidationError constructor signatures between common.server.ts and errors.ts

The PR adds logLevel as the 3rd parameter in apps/webapp/app/v3/services/common.server.ts (message, status?, logLevel?) but as the 4th parameter in internal-packages/run-engine/src/engine/errors.ts (message, status?, metadata?, logLevel?). All callers modified in this PR use the common.server.ts version, so the current code is correct. However, this signature divergence is a maintenance risk — a developer creating a ServiceValidationError from the run-engine package with new ServiceValidationError(msg, undefined, "warn") would accidentally assign "warn" to metadata instead of logLevel. Consider aligning the signatures or renaming one class to prevent confusion.

(Refers to lines 74-84)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Member Author

Choose a reason for hiding this comment

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

MCP test reply

Copy link
Member Author

Choose a reason for hiding this comment

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

MCP test reply

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal-packages/run-engine/src/engine/errors.ts (1)

72-84: ⚠️ Potential issue | 🟡 Minor

Remove the incorrect claim about 3-argument form misuse; the divergent ServiceValidationError classes are intentional architectural separation.

The ServiceValidationError class in run-engine has a different constructor signature than the one in apps/webapp/app/v3/services/common.server.ts:

  • run-engine: (message, status?, metadata?, logLevel?)
  • webapp/common.server.ts: (message, status?, logLevel?)

However, the webapp services (batchTriggerV3.server.ts, triggerTask.server.ts) only use the single-argument form new ServiceValidationError("message"), not the 3-argument form mentioned. The two versions are deliberately separated via different export names (EngineServiceValidationError vs ServiceValidationError) and handled with explicit instanceof checks in error handlers, indicating this is intentional during the V1→V2 migration. The current architecture properly isolates these distinct versions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal-packages/run-engine/src/engine/errors.ts` around lines 72 - 84,
Remove the incorrect assertion that the 3-argument constructor form is being
misused and clarify that the divergent constructors are intentional; update or
delete any nearby comment/documentation referring to a "3-argument form misuse"
around the ServiceValidationError class so it no longer claims misuse, and
explicitly note (if needed) that ServiceValidationError (this class) and
EngineServiceValidationError are intentionally different and handled via
instanceof checks in error handlers like those referenced in the webapp
services.
packages/redis-worker/src/worker.ts (1)

898-919: ⚠️ Potential issue | 🟡 Minor

logLevel is honored for processItem, but batch failures still ignore it.

This hunk correctly downgrades single-item logs, but processBatch still logs with the old binary error/info path, so batch-thrown ServiceValidationError(logLevel: "warn" | "info") won’t be respected.

🧩 Suggested parity update for batch path
@@
-      const shouldLogError = catalogItem.logErrors ?? true;
+      const shouldLogError = catalogItem.logErrors ?? true;
+      const errorLogLevel =
+        error && typeof error === "object" && "logLevel" in error ? error.logLevel : undefined;
@@
-      if (shouldLogError) {
-        this.logger.error(`Worker error processing batch`, {
+      if (!shouldLogError || errorLogLevel === "info") {
+        this.logger.info(`Worker failed to process batch`, {
           name: this.options.name,
           jobType,
           batchSize: items.length,
           error,
           errorMessage,
         });
-      } else {
-        this.logger.info(`Worker failed to process batch`, {
+      } else if (errorLogLevel === "warn") {
+        this.logger.warn(`Worker error processing batch`, {
           name: this.options.name,
           jobType,
           batchSize: items.length,
           error,
           errorMessage,
         });
+      } else {
+        this.logger.error(`Worker error processing batch`, {
+          name: this.options.name,
+          jobType,
+          batchSize: items.length,
+          error,
+          errorMessage,
+        });
       }
@@
-          if (!retryDelay) {
-            if (shouldLogError) {
+          if (!retryDelay) {
+            if (!shouldLogError || errorLogLevel === "info") {
+              this.logger.info(`Worker batch item reached max attempts. Moving to DLQ.`, {
+                name: this.options.name,
+                id: item.id,
+                jobType,
+                attempt: newAttempt,
+              });
+            } else if (errorLogLevel === "warn") {
+              this.logger.warn(`Worker batch item reached max attempts. Moving to DLQ.`, {
+                name: this.options.name,
+                id: item.id,
+                jobType,
+                attempt: newAttempt,
+              });
+            } else {
               this.logger.error(`Worker batch item reached max attempts. Moving to DLQ.`, {
                 name: this.options.name,
                 id: item.id,
                 jobType,
                 attempt: newAttempt,
               });
-            } else {
-              this.logger.info(`Worker batch item reached max attempts. Moving to DLQ.`, {
-                name: this.options.name,
-                id: item.id,
-                jobType,
-                attempt: newAttempt,
-              });
             }

Also applies to: 931-943

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/redis-worker/src/worker.ts` around lines 898 - 919, The batch
failure logging path in processBatch must mirror the single-item handling so
ServiceValidationError.logLevel is respected: in the processBatch error branch
compute errorLogLevel the same way (check error && typeof error === "object" &&
"logLevel" in error), build the same logAttributes (name, id, job, item(s),
visibilityTimeoutMs, error, errorMessage), and replace the current binary
logger.info/error calls with the same conditional that calls logger.warn if
errorLogLevel === "warn", logger.info if errorLogLevel === "info", otherwise
logger.error; apply this change to the processBatch error handling blocks
referenced around the existing shouldLogError logic so both paths are
consistent.
🧹 Nitpick comments (2)
apps/webapp/app/v3/scheduleEngine.server.ts (1)

115-130: Consider using logLevel property for more robust detection.

The current string matching approach is fragile—if the error message wording changes, the detection will silently break and queue limit errors will be misclassified as SYSTEM_ERROR.

Since ServiceValidationError now has a logLevel property, consider checking it instead:

 if (
   error instanceof ServiceValidationError &&
-  errorMessage.includes("queue size limit for this environment has been reached")
+  error.logLevel === "warn"
 ) {
   errorType = "QUEUE_LIMIT";
 }

This would be more maintainable and wouldn't break if the error message text is refactored. However, if there are other "warn"-level ServiceValidationError cases that shouldn't be classified as QUEUE_LIMIT, the current approach is acceptable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/webapp/app/v3/scheduleEngine.server.ts` around lines 115 - 130, Replace
the fragile message substring check in the catch block with a check of the
ServiceValidationError.logLevel property: when error is an instance of
ServiceValidationError and error.logLevel === "warn" set errorType to
"QUEUE_LIMIT" (instead of relying on the message text). Update the conditional
that currently inspects errorMessage.includes(...) to check error.logLevel,
keeping the surrounding return object (success, error, errorType) and types like
TriggerScheduledTaskErrorType unchanged.
internal-packages/schedule-engine/src/engine/types.ts (1)

29-34: Prefer a type alias and a discriminated result union for the callback return.

Line 29 keeps TriggerScheduledTaskCallback as an interface, and Lines 30-34 allow invalid combinations (success: true with errorType). Converting this to type aliases with a discriminated union makes states explicit and aligns with repo TS conventions.

♻️ Proposed refactor
 export type TriggerScheduledTaskErrorType = "QUEUE_LIMIT" | "SYSTEM_ERROR";
 
-export interface TriggerScheduledTaskCallback {
-  (params: TriggerScheduledTaskParams): Promise<{
-    success: boolean;
-    error?: string;
-    errorType?: TriggerScheduledTaskErrorType;
-  }>;
-}
+export type TriggerScheduledTaskResult =
+  | { success: true }
+  | {
+      success: false;
+      error: string;
+      errorType?: TriggerScheduledTaskErrorType;
+    };
+
+export type TriggerScheduledTaskCallback = (
+  params: TriggerScheduledTaskParams
+) => Promise<TriggerScheduledTaskResult>;

As per coding guidelines: **/*.{ts,tsx}: Use types over interfaces for TypeScript.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal-packages/schedule-engine/src/engine/types.ts` around lines 29 - 34,
Replace the interface-based callback with type aliases and a discriminated union
return: change TriggerScheduledTaskCallback (which currently references
TriggerScheduledTaskParams) from an interface to a type alias and define a
result union such that one branch is { success: true } and the other is {
success: false; error: string; errorType?: TriggerScheduledTaskErrorType } (or
include errorType required if intended), eliminating invalid combinations like
success:true with error fields; update the callback signature to return
Promise<ThatDiscriminatedUnion> and keep references to
TriggerScheduledTaskParams and TriggerScheduledTaskErrorType intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@internal-packages/run-engine/src/engine/errors.ts`:
- Around line 72-84: Remove the incorrect assertion that the 3-argument
constructor form is being misused and clarify that the divergent constructors
are intentional; update or delete any nearby comment/documentation referring to
a "3-argument form misuse" around the ServiceValidationError class so it no
longer claims misuse, and explicitly note (if needed) that
ServiceValidationError (this class) and EngineServiceValidationError are
intentionally different and handled via instanceof checks in error handlers like
those referenced in the webapp services.

In `@packages/redis-worker/src/worker.ts`:
- Around line 898-919: The batch failure logging path in processBatch must
mirror the single-item handling so ServiceValidationError.logLevel is respected:
in the processBatch error branch compute errorLogLevel the same way (check error
&& typeof error === "object" && "logLevel" in error), build the same
logAttributes (name, id, job, item(s), visibilityTimeoutMs, error,
errorMessage), and replace the current binary logger.info/error calls with the
same conditional that calls logger.warn if errorLogLevel === "warn", logger.info
if errorLogLevel === "info", otherwise logger.error; apply this change to the
processBatch error handling blocks referenced around the existing shouldLogError
logic so both paths are consistent.

---

Nitpick comments:
In `@apps/webapp/app/v3/scheduleEngine.server.ts`:
- Around line 115-130: Replace the fragile message substring check in the catch
block with a check of the ServiceValidationError.logLevel property: when error
is an instance of ServiceValidationError and error.logLevel === "warn" set
errorType to "QUEUE_LIMIT" (instead of relying on the message text). Update the
conditional that currently inspects errorMessage.includes(...) to check
error.logLevel, keeping the surrounding return object (success, error,
errorType) and types like TriggerScheduledTaskErrorType unchanged.

In `@internal-packages/schedule-engine/src/engine/types.ts`:
- Around line 29-34: Replace the interface-based callback with type aliases and
a discriminated union return: change TriggerScheduledTaskCallback (which
currently references TriggerScheduledTaskParams) from an interface to a type
alias and define a result union such that one branch is { success: true } and
the other is { success: false; error: string; errorType?:
TriggerScheduledTaskErrorType } (or include errorType required if intended),
eliminating invalid combinations like success:true with error fields; update the
callback signature to return Promise<ThatDiscriminatedUnion> and keep references
to TriggerScheduledTaskParams and TriggerScheduledTaskErrorType intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3b5afe32-d726-48da-9af0-7aeac5082321

📥 Commits

Reviewing files that changed from the base of the PR and between 35298ac and 969973c.

📒 Files selected for processing (10)
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/run-engine/src/engine/errors.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • internal-packages/schedule-engine/src/index.ts
  • packages/redis-worker/src/worker.ts
📜 Review details
⏰ 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). (27)
  • 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 (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 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 (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 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 (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: sdk-compat / Node.js 22.12 (ubuntu-latest)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: sdk-compat / Bun Runtime
  • GitHub Check: typecheck / typecheck
  • GitHub Check: sdk-compat / Node.js 20.20 (ubuntu-latest)
  • GitHub Check: sdk-compat / Cloudflare Workers
  • GitHub Check: sdk-compat / Deno Runtime
🧰 Additional context used
📓 Path-based instructions (16)
**/*.{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

**/*.{ts,tsx}: Use task export syntax: export const myTask = task({ id: 'my-task', run: async (payload) => { ... } })
Use Run Engine 2.0 (@internal/run-engine) and redis-worker for all new work - avoid DEPRECATED zodworker (Graphile-worker wrapper)
Prisma 6.14.0 client and schema use PostgreSQL in internal-packages/database - import only from Prisma client

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.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/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
**/*.{ts,tsx,js,jsx}

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

Use function declarations instead of default exports

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.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/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.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/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
apps/webapp/app/v3/services/**/*.server.{ts,tsx}

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

Organize services in the webapp following the pattern app/v3/services/*/*.server.ts

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/v3/services/common.server.ts
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)

**/*.ts: When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs
Do not use high-cardinality attributes in OTEL metrics such as UUIDs/IDs (envId, userId, runId, projectId, organizationId), unbounded integers (itemCount, batchSize, retryCount), timestamps (createdAt, startTime), or free-form strings (errorMessage, taskName, queueName)
When exporting OTEL metrics via OTLP to Prometheus, be aware that the exporter automatically adds unit suffixes to metric names (e.g., 'my_duration_ms' becomes 'my_duration_ms_milliseconds', 'my_counter' becomes 'my_counter_total'). Account for these transformations when writing Grafana dashboards or Prometheus queries

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.ts
**/*.{js,ts,jsx,tsx,json,md,yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier before committing

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.ts
apps/webapp/**/*.server.ts

📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)

Access environment variables via the env export from app/env.server.ts, never use process.env directly

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
apps/webapp/app/v3/services/**/*.server.ts

📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)

When editing services that branch on RunEngineVersion to support both V1 and V2 (e.g., cancelTaskRun.server.ts, batchTriggerV3.server.ts), only modify V2 code paths

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/v3/services/common.server.ts
apps/{webapp,supervisor}/**/*

📄 CodeRabbit inference engine (CLAUDE.md)

When modifying only server components (apps/webapp/, apps/supervisor/) with no package changes, add a .server-changes/ file instead of a changeset

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js}: Always import from @trigger.dev/sdk for Trigger.dev tasks - never use @trigger.dev/sdk/v3 or deprecated client.defineJob
Import subpaths only from @trigger.dev/core, never import from root
Add crumbs as you write code using // @crumbs comments or // #region @crumbs blocks for agentcrumbs debug tracing

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.ts
apps/webapp/app/v3/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

When modifying V3 code paths in apps/webapp/app/v3/, only modify V2 code - consult apps/webapp/CLAUDE.md for V1-only legacy code to avoid

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
apps/webapp/**/*.{ts,tsx,jsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Remix 2.1.0 is used in apps/webapp for the main API, dashboard, and orchestration with Express server

Files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
packages/redis-worker/**/*@(job|queue|worker|background).{ts,tsx}

📄 CodeRabbit inference engine (packages/redis-worker/CLAUDE.md)

Use @trigger.dev/redis-worker for all new background job implementations, replacing graphile-worker and zodworker

Files:

  • packages/redis-worker/src/worker.ts
{packages,integrations}/**/*.{ts,tsx,js,json}

📄 CodeRabbit inference engine (CLAUDE.md)

When modifying public packages (packages/* or integrations/*), add a changeset using pnpm run changeset:add with default patch level for bug fixes and minor changes

Files:

  • packages/redis-worker/src/worker.ts
🧠 Learnings (36)
📚 Learning: 2026-03-02T12:42:56.114Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: apps/webapp/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:56.114Z
Learning: Applies to apps/webapp/app/v3/services/**/*.server.ts : When editing services that branch on `RunEngineVersion` to support both V1 and V2 (e.g., `cancelTaskRun.server.ts`, `batchTriggerV3.server.ts`), only modify V2 code paths

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
  • apps/webapp/app/v3/services/common.server.ts
  • internal-packages/run-engine/src/engine/errors.ts
📚 Learning: 2026-03-02T12:42:56.114Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: apps/webapp/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:56.114Z
Learning: Applies to apps/webapp/app/v3/*Worker.server.ts : New background job workers should use `trigger.dev/redis-worker` (e.g., `commonWorker.server.ts`, `alertsWorker.server.ts`, `batchTriggerWorker.server.ts`), not zodworker or graphile-worker

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • packages/redis-worker/src/worker.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-02-10T16:18:48.654Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 2980
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx:512-515
Timestamp: 2026-02-10T16:18:48.654Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues/route.tsx, environment.queueSizeLimit is a per-queue maximum that is configured at the environment level, not a shared limit across all queues. Each queue can have up to environment.queueSizeLimit items queued independently.

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2026-03-03T13:08:03.862Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3166
File: packages/redis-worker/src/fair-queue/index.ts:1114-1121
Timestamp: 2026-03-03T13:08:03.862Z
Learning: In packages/redis-worker/src/fair-queue/index.ts, it's acceptable for the worker queue depth cap check to allow overshooting by up to batchClaimSize messages per iteration, as the next iteration will recheck and prevent sustained growth beyond the limit.

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • packages/redis-worker/src/worker.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:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-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.batchTrigger()` to trigger multiple runs of a task from inside another task

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
📚 Learning: 2026-03-10T17:56:20.938Z
Learnt from: samejr
Repo: triggerdotdev/trigger.dev PR: 3201
File: apps/webapp/app/v3/services/setSeatsAddOn.server.ts:25-29
Timestamp: 2026-03-10T17:56:20.938Z
Learning: Do not implement local userId-to-organizationId authorization checks inside org-scoped service classes (e.g., SetSeatsAddOnService, SetBranchesAddOnService) in the web app. Rely on route-layer authentication (requireUserId(request)) and org membership enforcement via the _app.orgs.$organizationSlug layout route. Any userId/organizationId that reaches these services from org-scoped routes has already been validated. Apply this pattern across all org-scoped services to avoid redundant auth checks and maintain consistency.

Applied to files:

  • apps/webapp/app/v3/services/batchTriggerV3.server.ts
  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/v3/services/common.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/v3/services/triggerTaskV1.server.ts
  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-03-02T12:43:37.906Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/core/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:37.906Z
Learning: Exercise caution with changes to trigger.dev/core as they affect both the customer-facing SDK and server-side webapp - breaking changes can impact deployed user tasks and the platform simultaneously

Applied to files:

  • apps/webapp/app/v3/services/triggerTaskV1.server.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:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.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/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.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.triggerByTask()` to batch trigger tasks by passing task instances for static task sets

Applied to files:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-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:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-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.triggerByTaskAndWait()` to batch trigger tasks by passing task instances and wait for results

Applied to files:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-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:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • apps/webapp/app/v3/scheduleEngine.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:

  • apps/webapp/app/v3/services/triggerTaskV1.server.ts
  • internal-packages/schedule-engine/src/index.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-03-13T13:37:49.562Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T13:37:49.562Z
Learning: Applies to **/*.{ts,tsx} : Use Run Engine 2.0 (internal/run-engine) and redis-worker for all new work - avoid DEPRECATED zodworker (Graphile-worker wrapper)

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • packages/redis-worker/src/worker.ts
📚 Learning: 2024-10-18T15:41:52.352Z
Learnt from: nicktrn
Repo: triggerdotdev/trigger.dev PR: 1418
File: packages/core/src/v3/errors.ts:364-371
Timestamp: 2024-10-18T15:41:52.352Z
Learning: In `packages/core/src/v3/errors.ts`, within the `taskRunErrorEnhancer` function, `error.message` is always defined, so it's safe to directly call `error.message.includes("SIGTERM")` without additional checks.

Applied to files:

  • apps/webapp/app/runEngine/services/triggerTask.server.ts
  • apps/webapp/app/v3/scheduleEngine.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/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.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:

  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.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 every task, including subtasks

Applied to files:

  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-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 cron schedules declaratively using the `cron` property or imperatively using `schedules.create()`

Applied to files:

  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.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/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-03-13T13:37:49.562Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T13:37:49.562Z
Learning: Applies to **/*.{ts,tsx,js} : Always import from trigger.dev/sdk for Trigger.dev tasks - never use trigger.dev/sdk/v3 or deprecated client.defineJob

Applied to files:

  • internal-packages/schedule-engine/src/index.ts
📚 Learning: 2026-03-13T13:37:49.562Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-13T13:37:49.562Z
Learning: Applies to **/*.{ts,tsx} : Use task export syntax: export const myTask = task({ id: 'my-task', run: async (payload) => { ... } })

Applied to files:

  • internal-packages/schedule-engine/src/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:

  • internal-packages/schedule-engine/src/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-01-08T15:57:09.323Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/otel-metrics.mdc:0-0
Timestamp: 2026-01-08T15:57:09.323Z
Learning: Reference the schedule engine (internal-packages/schedule-engine/src/engine/index.ts) as a good example of implementing low-cardinality metric attributes

Applied to files:

  • internal-packages/schedule-engine/src/engine/index.ts
  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-03-03T13:07:33.177Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3166
File: internal-packages/run-engine/src/batch-queue/tests/index.test.ts:711-713
Timestamp: 2026-03-03T13:07:33.177Z
Learning: In `internal-packages/run-engine/src/batch-queue/tests/index.test.ts`, test assertions for rate limiter stubs can use `toBeGreaterThanOrEqual` rather than exact equality (`toBe`) because the consumer loop may call the rate limiter during empty pops in addition to actual item processing, and this over-calling is acceptable in integration tests.

Applied to files:

  • internal-packages/schedule-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} : Limit task duration using the `maxDuration` property (in seconds)

Applied to files:

  • internal-packages/schedule-engine/src/engine/index.ts
  • internal-packages/schedule-engine/src/engine/types.ts
📚 Learning: 2026-03-02T12:43:43.173Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/redis-worker/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:43.173Z
Learning: Applies to packages/redis-worker/**/redis-worker/src/worker.ts : Worker loop and job processing should implement concurrency control in src/worker.ts

Applied to files:

  • packages/redis-worker/src/worker.ts
📚 Learning: 2026-03-02T12:43:43.173Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/redis-worker/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:43.173Z
Learning: Applies to packages/redis-worker/**/redis-worker/src/queue.ts : Job queue abstraction should be Redis-backed in src/queue.ts

Applied to files:

  • packages/redis-worker/src/worker.ts
📚 Learning: 2026-03-02T12:43:43.173Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: packages/redis-worker/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:43:43.173Z
Learning: Applies to packages/redis-worker/**/*@(job|queue|worker|background).{ts,tsx} : Use trigger.dev/redis-worker for all new background job implementations, replacing graphile-worker and zodworker

Applied to files:

  • packages/redis-worker/src/worker.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 : Define global lifecycle functions (onStart, onSuccess, onFailure) in trigger.config.ts to apply to all tasks

Applied to files:

  • apps/webapp/app/v3/scheduleEngine.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 OpenTelemetry instrumentations and exporters in trigger.config.ts for enhanced logging

Applied to files:

  • apps/webapp/app/v3/scheduleEngine.server.ts
📚 Learning: 2026-03-02T12:42:56.114Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: apps/webapp/CLAUDE.md:0-0
Timestamp: 2026-03-02T12:42:56.114Z
Learning: All run lifecycle operations (triggering, completing, cancelling, etc.) should be performed through the singleton run engine instance in `app/v3/runEngine.server.ts` via service calls

Applied to files:

  • apps/webapp/app/v3/scheduleEngine.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: Applies to apps/webapp/app/v3/services/**/*.server.{ts,tsx} : Organize services in the webapp following the pattern `app/v3/services/*/*.server.ts`

Applied to files:

  • apps/webapp/app/v3/services/common.server.ts
🔇 Additional comments (6)
apps/webapp/app/v3/services/common.server.ts (1)

1-12: LGTM!

The ServiceValidationErrorLevel type and updated constructor signature are correct. The 3-parameter signature (message, status?, logLevel?) aligns with how webapp services call it with (message, undefined, "warn").

internal-packages/schedule-engine/src/index.ts (1)

1-7: LGTM!

The re-export of TriggerScheduledTaskErrorType properly exposes the type for consumers like scheduleEngine.server.ts.

apps/webapp/app/v3/services/batchTriggerV3.server.ts (1)

250-256: LGTM!

The queue limit error correctly uses "warn" log level. The error message text contains the substring that scheduleEngine.server.ts uses for detection.

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

264-270: LGTM!

The queue limit error correctly uses the "warn" log level with consistent error message formatting.

apps/webapp/app/v3/services/triggerTaskV1.server.ts (1)

135-141: LGTM!

The queue limit error correctly uses "warn" log level. While this is V1 code (marked deprecated), the change is justified to ensure consistent logging behavior across all code paths that throw queue limit errors.

internal-packages/schedule-engine/src/engine/index.ts (1)

499-528: LGTM!

The implementation correctly:

  1. Checks result.errorType === "QUEUE_LIMIT" to identify queue limit failures
  2. Logs queue limit failures as warnings instead of errors
  3. Uses low-cardinality error_type attribute values ("queue_limit" | "task_failure") for the failure counter metric

This aligns with the PR objective of reducing noise from expected validation rejections.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines +911 to +918
if (!shouldLogError) {
this.logger.info(`Worker failed to process item`, logAttributes);
} else if (errorLogLevel === "warn") {
this.logger.warn(`Worker error processing item`, logAttributes);
} else if (errorLogLevel === "info") {
this.logger.info(`Worker error processing item`, logAttributes);
} else {
this.logger.error(`Worker error processing item`, logAttributes);
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 logLevel-aware error logging not applied to processBatchItems, only to processItem

The new errorLogLevel handling (reading error.logLevel to control log severity) was added to processItem at packages/redis-worker/src/worker.ts:898 but was not applied to the analogous error-handling block in processBatchItems (packages/redis-worker/src/worker.ts:798-828). The batch item error handler still uses only the binary shouldLogError check and always logs at error level when shouldLogError is true. If a batch job handler throws an error with logLevel: "warn" or logLevel: "info", the batch processing path will still log it as error, defeating the purpose of the logLevel feature for batch-processed jobs.

Prompt for agents
In packages/redis-worker/src/worker.ts, the processBatchItems method (around lines 798-828) has an error handling block that should mirror the new errorLogLevel-aware logging added to processItem at lines 897-918. Specifically, after line ~797 in the batch error handler, add the same errorLogLevel extraction:

const errorLogLevel = error && typeof error === "object" && "logLevel" in error ? error.logLevel : undefined;

Then replace the simple shouldLogError/else branch with the same 4-way branch used in processItem:
- if (!shouldLogError) -> logger.info
- else if (errorLogLevel === "warn") -> logger.warn
- else if (errorLogLevel === "info") -> logger.info
- else -> logger.error

Also apply the same pattern to the max-attempts/DLQ logging block that follows the error logging in processBatchItems.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant