fix: downgrade queue size limit errors to warnings#3243
fix: downgrade queue size limit errors to warnings#3243
Conversation
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
|
WalkthroughThis change introduces error-level classification for Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment Tip CodeRabbit can suggest fixes for GitHub Check annotations.Configure the |
| 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"; |
There was a problem hiding this comment.
🚩 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)
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
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 | 🟡 MinorRemove the incorrect claim about 3-argument form misuse; the divergent
ServiceValidationErrorclasses are intentional architectural separation.The
ServiceValidationErrorclass in run-engine has a different constructor signature than the one inapps/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 formnew ServiceValidationError("message"), not the 3-argument form mentioned. The two versions are deliberately separated via different export names (EngineServiceValidationErrorvsServiceValidationError) and handled with explicitinstanceofchecks 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
logLevelis honored forprocessItem, but batch failures still ignore it.This hunk correctly downgrades single-item logs, but
processBatchstill logs with the old binaryerror/infopath, so batch-thrownServiceValidationError(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 usinglogLevelproperty 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
ServiceValidationErrornow has alogLevelproperty, 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"-levelServiceValidationErrorcases that shouldn't be classified asQUEUE_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 atypealias and a discriminated result union for the callback return.Line 29 keeps
TriggerScheduledTaskCallbackas aninterface, and Lines 30-34 allow invalid combinations (success: truewitherrorType). 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
📒 Files selected for processing (10)
apps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/batchTriggerV3.server.tsapps/webapp/app/v3/services/common.server.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsinternal-packages/run-engine/src/engine/errors.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tsinternal-packages/schedule-engine/src/index.tspackages/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tspackages/redis-worker/src/worker.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tspackages/redis-worker/src/worker.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-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
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/v3/services/batchTriggerV3.server.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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/corein 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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tspackages/redis-worker/src/worker.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tspackages/redis-worker/src/worker.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-packages/run-engine/src/engine/errors.ts
apps/webapp/**/*.server.ts
📄 CodeRabbit inference engine (apps/webapp/CLAUDE.md)
Access environment variables via the
envexport fromapp/env.server.ts, never useprocess.envdirectly
Files:
apps/webapp/app/v3/services/batchTriggerV3.server.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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
RunEngineVersionto 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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.ts
**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js}: Always import from@trigger.dev/sdkfor Trigger.dev tasks - never use@trigger.dev/sdk/v3or deprecated client.defineJob
Import subpaths only from@trigger.dev/core, never import from root
Add crumbs as you write code using //@crumbscomments or //#region@crumbsblocks for agentcrumbs debug tracing
Files:
apps/webapp/app/v3/services/batchTriggerV3.server.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tspackages/redis-worker/src/worker.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/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-workerfor 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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsapps/webapp/app/v3/scheduleEngine.server.tsapps/webapp/app/v3/services/common.server.tsinternal-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.tsapps/webapp/app/runEngine/services/triggerTask.server.tspackages/redis-worker/src/worker.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/engine/index.tspackages/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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-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.tsapps/webapp/app/v3/services/triggerTaskV1.server.tsapps/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.tsapps/webapp/app/runEngine/services/triggerTask.server.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsapps/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.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-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.tsinternal-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.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-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.tsinternal-packages/schedule-engine/src/index.tsinternal-packages/schedule-engine/src/engine/index.tsapps/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.tsinternal-packages/schedule-engine/src/index.tsapps/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.tspackages/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.tsapps/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.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-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.tsinternal-packages/schedule-engine/src/engine/index.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsinternal-packages/schedule-engine/src/engine/types.tsapps/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.tsapps/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.tsinternal-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
ServiceValidationErrorLeveltype 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
TriggerScheduledTaskErrorTypeproperly exposes the type for consumers likescheduleEngine.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 thatscheduleEngine.server.tsuses 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:
- Checks
result.errorType === "QUEUE_LIMIT"to identify queue limit failures- Logs queue limit failures as warnings instead of errors
- Uses low-cardinality
error_typeattribute values ("queue_limit"|"task_failure") for the failure counter metricThis aligns with the PR objective of reducing noise from expected validation rejections.
Queue limit ServiceValidationErrors were being logged at error level. These are
expected validation rejections, not bugs.