-
-
Notifications
You must be signed in to change notification settings - Fork 852
fix(webapp): worker actions now catch service validation errors and respond properly #2481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
WalkthroughImports and usages of a local EngineServiceValidationError were replaced with a centralized ServiceValidationError across runEngine modules (payloads, queues, validators, trigger service). The local EngineServiceValidationError class was removed from the webapp. internal-packages/run-engine now re-exports ServiceValidationError under the alias EngineServiceValidationError. API route builders explicitly handle both EngineServiceValidationError and ServiceValidationError. RunLocker.lock now rethrows ServiceValidationError immediately (skipping metric/log steps). One import ordering change in engine/index.ts; no public method signatures were altered. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Pre-merge checks (1 passed, 2 warnings)❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (21)
internal-packages/run-engine/src/engine/locking.ts (1)
183-188
: Avoid double-counting lock duration on failuresFailure duration is recorded here and also in #acquireAndExecute finally; that can double count. Prefer recording only inside #acquireAndExecute.
Apply:
- const lockDuration = performance.now() - lockStartTime; - this.lockDurationHistogram.record(lockDuration, { - [SemanticAttributes.LOCK_TYPE]: name, - [SemanticAttributes.LOCK_SUCCESS]: "false", - }); + // Duration recorded in #acquireAndExecute.finally; avoid duplicate metric here.Also applies to: 396-401
apps/webapp/app/runEngine/concerns/payloads.server.ts (1)
38-40
: Preserve diagnostics in metadata for easier debuggingInclude filename/size/env in the error metadata so callers have actionable context.
Apply:
- throw new ServiceValidationError("Failed to upload large payload to object store", 500); // This is retryable + throw new ServiceValidationError( + "Failed to upload large payload to object store", + 500, + { filename, size, envId: request.environment.id } + ); // This is retryableapps/webapp/app/runEngine/concerns/queues.server.ts (8)
48-53
: Return a 404 for missing specified queueSurface the correct status for upstream handlers and clients.
- throw new ServiceValidationError( + throw new ServiceValidationError( `Specified queue '${specifiedQueueName}' not found or not associated with locked version '${lockedBackgroundWorker.version ?? "<unknown>"}'.` - ); + , 404);
71-76
: Return a 404 when the task isn’t on the locked versionAligns status with “not found”.
- throw new ServiceValidationError( + throw new ServiceValidationError( `Task '${request.taskId}' not found on locked version '${lockedBackgroundWorker.version ?? "<unknown>"}'.` - ); + , 404);
86-90
: Consider 422 (bad configuration) or 500 (server) for missing default queueUse a non-404 status to reflect config/state issue; 422 keeps it client-visible without implying server fault.
- throw new ServiceValidationError( + throw new ServiceValidationError( `Default queue configuration for task '${request.taskId}' missing on locked version '${lockedBackgroundWorker.version ?? "<unknown>"}'.` - ); + , 422);
100-102
: Use 404 when lockToVersion references a non-existent workerImproves accuracy of responses.
- throw new ServiceValidationError( + throw new ServiceValidationError( `Task locked to version '${request.body.options.lockToVersion}', but no worker found with that version.` - ); + , 404);
112-117
: Re-sanitize fallback to guarantee a non-empty queue nameGuard against sanitize producing an empty string twice.
- if (!sanitizedQueueName) { - queueName = sanitizeQueueName(`task/${request.taskId}`); // Fallback if sanitization results in empty - } else { - queueName = sanitizedQueueName; - } + if (!sanitizedQueueName) { + const fallback = sanitizeQueueName(`task/${request.taskId}`); + queueName = fallback || "task/default"; + } else { + queueName = sanitizedQueueName; + }
223-225
: Preserve status when rethrowing known validation errorsIf the service threw ServiceValidationError, propagate it; otherwise wrap generically.
- if (error) { - throw new ServiceValidationError(error.message); - } + if (error) { + if (error instanceof ServiceValidationError) throw error; + throw new ServiceValidationError(error.message); + }
228-229
: Use 404 for missing worker groupMatch semantics for “not found”.
- throw new ServiceValidationError("No worker group found"); + throw new ServiceValidationError("No worker group found", 404);
159-175
: Replace console.log with logger to keep logs structuredStay consistent with the rest of the module.
- console.log("Failed to get queue name: No task found", { + logger.debug("Failed to get queue name: No task found", { taskId, environmentId: environment.id, }); ... - console.log("Failed to get queue name: No queue found", { + logger.debug("Failed to get queue name: No queue found", { taskId, environmentId: environment.id, queueConfig: task.queueConfig, });Also applies to: 168-175
internal-packages/run-engine/src/index.ts (1)
2-6
: Optionally re-export the base name too for gradual migration.Expose
ServiceValidationError
alongside the alias so call sites can migrate without reaching into subpaths.Apply:
export { RunDuplicateIdempotencyKeyError, RunOneTimeUseTokenError, + ServiceValidationError, ServiceValidationError as EngineServiceValidationError, } from "./engine/errors.js";
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts (3)
1049-1055
: Deduplicate the two instanceof checks.Combine the branches to reduce repetition and guard against subtle ordering mistakes.
Apply:
- if (error instanceof EngineServiceValidationError) { - return json({ error: error.message }, { status: error.status ?? 422 }); - } - - if (error instanceof ServiceValidationError) { - return json({ error: error.message }, { status: error.status ?? 422 }); - } + if ( + error instanceof EngineServiceValidationError || + error instanceof ServiceValidationError + ) { + return json({ error: (error as any).message }, { status: (error as any).status ?? 422 }); + }
877-877
: Drop console.error and rely on structured logger.Avoid double-logging and keep output consistent with
logger.error
.Apply:
- console.error("Error in API route:", error);
733-749
: Mirror ServiceValidationError handling in public action routes.For parity with worker actions, return 4xx for validation errors before logging.
Apply:
} catch (error) { try { if (error instanceof Response) { return await wrapResponse(request, error, corsStrategy !== "none"); } + if ( + error instanceof EngineServiceValidationError || + error instanceof ServiceValidationError + ) { + return await wrapResponse( + request, + json({ error: (error as any).message }, { status: (error as any).status ?? 422 }), + corsStrategy !== "none" + ); + } logger.error("Error in action", {apps/webapp/app/runEngine/services/triggerTask.server.ts (4)
160-161
: Set an explicit HTTP status for invalid delay.Make the intent clear for downstream mappers returning 4xx.
Apply:
- throw new ServiceValidationError(`Invalid delay ${body.options?.delay}`); + throw new ServiceValidationError(`Invalid delay ${body.options?.delay}`, 422);
213-216
: Provide status for queue limit validation.Consider 429 (Too Many Requests) to reflect capacity limits.
Apply:
- throw new ServiceValidationError( - `Cannot trigger ${taskId} as the queue size limit for this environment has been reached. The maximum size is ${queueSizeGuard.maximumSize}` - ); + throw new ServiceValidationError( + `Cannot trigger ${taskId} as the queue size limit for this environment has been reached. The maximum size is ${queueSizeGuard.maximumSize}`, + 429 + );
353-357
: Status for task-run error propagation.Mark as 422 to signal validation-like failure up the stack.
Apply:
- throw new ServiceValidationError( - taskRunErrorToString(taskRunErrorEnhancer(result.error)) - ); + throw new ServiceValidationError( + taskRunErrorToString(taskRunErrorEnhancer(result.error)), + 422 + );
368-371
: Status for one-time-use token violation.Return 422 (or 409) rather than defaulting.
Apply:
- throw new ServiceValidationError( - `Cannot trigger ${taskId} with a one-time use token as it has already been used.` - ); + throw new ServiceValidationError( + `Cannot trigger ${taskId} with a one-time use token as it has already been used.`, + 422 + );apps/webapp/app/runEngine/validators/triggerTaskValidator.ts (3)
32-35
: Return an explicit 422 for tag count violations.Helps route mappers choose the right status without guessing.
Apply:
- error: new ServiceValidationError( - `Runs can only have ${MAX_TAGS_PER_RUN} tags, you're trying to set ${tags.length}.` - ), + error: new ServiceValidationError( + `Runs can only have ${MAX_TAGS_PER_RUN} tags, you're trying to set ${tags.length}.`, + 422 + ),
68-71
: Use 429 for max-attempts exceeded.Communicates retry exhaustion/rate-like limit more precisely.
Apply:
- error: new ServiceValidationError( - `Failed to trigger ${taskId} after ${MAX_ATTEMPTS} attempts.` - ), + error: new ServiceValidationError( + `Failed to trigger ${taskId} after ${MAX_ATTEMPTS} attempts.`, + 429 + ),
98-101
: Use 409 for parent-run terminal-state conflict.Represents a conflict with current resource state.
Apply:
- error: new ServiceValidationError( - `Cannot trigger ${taskId} as the parent run has a status of ${parentRun.status}` - ), + error: new ServiceValidationError( + `Cannot trigger ${taskId} as the parent run has a status of ${parentRun.status}`, + 409 + ),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (10)
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
(1 hunks)apps/webapp/app/runEngine/concerns/errors.ts
(0 hunks)apps/webapp/app/runEngine/concerns/payloads.server.ts
(2 hunks)apps/webapp/app/runEngine/concerns/queues.server.ts
(6 hunks)apps/webapp/app/runEngine/services/triggerTask.server.ts
(5 hunks)apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
(4 hunks)apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
(2 hunks)internal-packages/run-engine/src/engine/index.ts
(1 hunks)internal-packages/run-engine/src/engine/locking.ts
(3 hunks)internal-packages/run-engine/src/index.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- apps/webapp/app/runEngine/concerns/errors.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}
: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations
Files:
internal-packages/run-engine/src/engine/locking.ts
internal-packages/run-engine/src/engine/index.ts
internal-packages/run-engine/src/index.ts
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/concerns/payloads.server.ts
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/concerns/queues.server.ts
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
We use zod a lot in packages/core and in the webapp
Files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/concerns/payloads.server.ts
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/concerns/queues.server.ts
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json
Files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/concerns/payloads.server.ts
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/concerns/queues.server.ts
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly
Files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/concerns/payloads.server.ts
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/concerns/queues.server.ts
apps/webapp/app/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead
Files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/concerns/payloads.server.ts
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/concerns/queues.server.ts
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
🧠 Learnings (8)
📚 Learning: 2025-08-29T10:06:49.293Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-08-29T10:06:49.293Z
Learning: Prefer Run Engine 2.0 via internal/run-engine; avoid extending legacy run engine code
Applied to files:
internal-packages/run-engine/src/index.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Do not use client.defineJob or any deprecated v2 patterns (e.g., eventTrigger) when defining tasks
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Import Trigger.dev APIs from "trigger.dev/sdk/v3" when writing tasks or related utilities
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Define tasks using task({ id, run, ... }) with a unique id per project
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schedules.task(...) for scheduled (cron) tasks; do not implement schedules as plain task() with external cron logic
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export every task (including subtasks) defined with task(), schedules.task(), or schemaTask()
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
📚 Learning: 2025-07-18T17:49:24.468Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-18T17:49:24.468Z
Learning: Applies to {packages/core,apps/webapp}/**/*.{ts,tsx} : We use zod a lot in packages/core and in the webapp
Applied to files:
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schemaTask({ schema, run, ... }) to validate payloads when input validation is required
Applied to files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
🧬 Code graph analysis (6)
internal-packages/run-engine/src/engine/locking.ts (1)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)
apps/webapp/app/runEngine/concerns/payloads.server.ts (2)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)internal-packages/run-engine/src/engine/errors.ts (1)
ServiceValidationError
(59-68)
apps/webapp/app/services/routeBuilders/apiBuilder.server.ts (2)
packages/core/src/v3/apps/http.ts (1)
json
(65-75)internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)
apps/webapp/app/runEngine/services/triggerTask.server.ts (4)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)internal-packages/run-engine/src/engine/errors.ts (1)
ServiceValidationError
(59-68)apps/webapp/app/v3/services/baseService.server.ts (1)
ServiceValidationError
(8-8)apps/webapp/app/v3/services/common.server.ts (1)
ServiceValidationError
(1-6)
apps/webapp/app/runEngine/concerns/queues.server.ts (2)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)internal-packages/run-engine/src/engine/errors.ts (1)
ServiceValidationError
(59-68)
apps/webapp/app/runEngine/validators/triggerTaskValidator.ts (2)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)internal-packages/run-engine/src/engine/errors.ts (1)
ServiceValidationError
(59-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 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 (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: typecheck / typecheck
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
internal-packages/run-engine/src/engine/locking.ts (3)
178-181
: Early rethrow correctly suppresses noisy lock logs/metricsShort-circuiting on ServiceValidationError here is the right call; it prevents misattributing routine failures to locking.
18-18
: Import source looks correctImporting ServiceValidationError from local errors module aligns with the new handling.
178-196
: Remove name‐based fallback;instanceof
is sufficientAll
ServiceValidationError
throw sites inrun-engine
import the same class from its ownerrors.js
(no mixed definitions), so theinstanceof ServiceValidationError
check will always match.apps/webapp/app/runEngine/concerns/payloads.server.ts (1)
6-6
: Centralized error importSwitch to the shared ServiceValidationError is consistent with the PR’s goal.
apps/webapp/app/runEngine/concerns/queues.server.ts (1)
17-17
: Centralized error importUsing the shared ServiceValidationError here keeps behavior consistent across the app.
internal-packages/run-engine/src/engine/index.ts (1)
32-32
: Import reordering only — OKNo behavioral impact.
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts (1)
1-1
: Updated import path for EngineServiceValidationError — OKImporting from @internal/run-engine (aliasing ServiceValidationError) keeps the route compatible with engine-thrown validation errors.
internal-packages/run-engine/src/index.ts (1)
2-6
: Alias export looks good for compat.Re-exporting
ServiceValidationError
asEngineServiceValidationError
preserves existing imports cleanly.apps/webapp/app/services/routeBuilders/apiBuilder.server.ts (1)
26-28
: Correct imports for both validation error sources.Importing
ServiceValidationError
(webapp) andEngineServiceValidationError
(run-engine alias) covers cross-package instanceof issues.
…espond properly This also stops all the unnecessary error logging when throwing ServiceValidationErrors
88785d4
to
d7f34c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
apps/webapp/app/runEngine/services/triggerTask.server.ts (5)
160-160
: Return an explicit 400 for invalid delay.Status helps route builders map responses without extra branching.
- throw new ServiceValidationError(`Invalid delay ${body.options?.delay}`); + throw new ServiceValidationError(`Invalid delay ${body.options?.delay}`, 400);
213-215
: Use a throttling-friendly status (429) for queue limit breaches.This better reflects a capacity condition and enables client retry/backoff strategies.
- throw new ServiceValidationError( - `Cannot trigger ${taskId} as the queue size limit for this environment has been reached. The maximum size is ${queueSizeGuard.maximumSize}` - ); + throw new ServiceValidationError( + `Cannot trigger ${taskId}: queue size limit reached (max ${queueSizeGuard.maximumSize}).`, + 429 + );
354-356
: Surface a 4xx for task-run validation failures.These are client/action errors, not 5xx.
- throw new ServiceValidationError( - taskRunErrorToString(taskRunErrorEnhancer(result.error)) - ); + throw new ServiceValidationError( + taskRunErrorToString(taskRunErrorEnhancer(result.error)), + 400 + );
368-371
: Prefer 409 for one-time token reuse.Token already used is a conflict, not a generic 400.
- throw new ServiceValidationError( - `Cannot trigger ${taskId} with a one-time use token as it has already been used.` - ); + throw new ServiceValidationError( + `Cannot trigger ${taskId} with a one-time use token: token already used.`, + 409 + );
43-43
: Unify error class source to avoid brittle instanceof checks.Multiple files import the local ServiceValidationError while other files import EngineServiceValidationError from @internal/run-engine — mixing distinct classes can break instanceof-based handlers. Import the canonical EngineServiceValidationError from @internal/run-engine (alias locally to ServiceValidationError if convenient) in runEngine-related files.
Affected runEngine files: apps/webapp/app/runEngine/concerns/queues.server.ts, apps/webapp/app/runEngine/concerns/payloads.server.ts, apps/webapp/app/runEngine/services/triggerTask.server.ts, apps/webapp/app/runEngine/services/batchTrigger.server.ts, apps/webapp/app/runEngine/validators/triggerTaskValidator.ts.
Example replacement in triggerTask.server.ts:
-import { ServiceValidationError } from "~/v3/services/common.server"; +import { EngineServiceValidationError as ServiceValidationError } from "@internal/run-engine";
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
(1 hunks)apps/webapp/app/runEngine/concerns/errors.ts
(0 hunks)apps/webapp/app/runEngine/concerns/payloads.server.ts
(2 hunks)apps/webapp/app/runEngine/concerns/queues.server.ts
(6 hunks)apps/webapp/app/runEngine/services/triggerTask.server.ts
(5 hunks)apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
(4 hunks)apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
(2 hunks)internal-packages/run-engine/src/engine/index.ts
(1 hunks)internal-packages/run-engine/src/engine/locking.ts
(3 hunks)internal-packages/run-engine/src/index.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- apps/webapp/app/runEngine/concerns/errors.ts
✅ Files skipped from review due to trivial changes (1)
- internal-packages/run-engine/src/engine/index.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- apps/webapp/app/services/routeBuilders/apiBuilder.server.ts
- apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts
- apps/webapp/app/runEngine/validators/triggerTaskValidator.ts
- internal-packages/run-engine/src/index.ts
- apps/webapp/app/runEngine/concerns/payloads.server.ts
- apps/webapp/app/runEngine/concerns/queues.server.ts
- internal-packages/run-engine/src/engine/locking.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}
: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations
Files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
We use zod a lot in packages/core and in the webapp
Files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json
Files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly
Files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
apps/webapp/app/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead
Files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
🧠 Learnings (4)
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Do not use client.defineJob or any deprecated v2 patterns (e.g., eventTrigger) when defining tasks
Applied to files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Define tasks using task({ id, run, ... }) with a unique id per project
Applied to files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Import Trigger.dev APIs from "trigger.dev/sdk/v3" when writing tasks or related utilities
Applied to files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
📚 Learning: 2025-08-18T10:07:17.368Z
Learnt from: CR
PR: triggerdotdev/trigger.dev#0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-08-18T10:07:17.368Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use schemaTask({ schema, run, ... }) to validate payloads when input validation is required
Applied to files:
apps/webapp/app/runEngine/services/triggerTask.server.ts
🧬 Code graph analysis (1)
apps/webapp/app/runEngine/services/triggerTask.server.ts (4)
internal-packages/run-engine/src/index.ts (1)
ServiceValidationError
(5-5)internal-packages/run-engine/src/engine/errors.ts (1)
ServiceValidationError
(59-68)apps/webapp/app/v3/services/baseService.server.ts (1)
ServiceValidationError
(8-8)apps/webapp/app/v3/services/common.server.ts (1)
ServiceValidationError
(1-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- 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 (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: typecheck / typecheck
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: Analyze (javascript-typescript)
Issues attributed to commits in this pull requestThis pull request was merged and Sentry observed the following issues:
Did you find this useful? React with a 👍 or 👎 |
This also stops all the unnecessary error logging when throwing
ServiceValidationErrors