Skip to content

Conversation

ericallam
Copy link
Member

This also stops all the unnecessary error logging when throwing
ServiceValidationErrors

Copy link

changeset-bot bot commented Sep 5, 2025

⚠️ No Changeset found

Latest commit: d7f34c7

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

Copy link
Contributor

coderabbitai bot commented Sep 5, 2025

Walkthrough

Imports 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)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The current PR description is insufficient and does not follow the repository template: it lacks the required "Closes #" line, the checklist, testing steps, a Changelog entry, and any screenshots or verification details, and only notes reduced error logging without describing how the change was tested or linked to an issue. Please update the PR description to use the provided template: add "Closes #" if applicable, complete the checklist items, include detailed testing steps and verification results, provide a short changelog summary of the behavioral change, and attach screenshots or logs demonstrating the reduced error logging and the new error-handling behavior.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately and concisely summarizes the primary change: updating worker action error handling so ServiceValidationErrors are caught and responded to correctly, which matches the changes across webapp route files and run-engine exports in the PR summary. It follows the conventional "fix(scope): summary" format and is clear for teammates scanning history.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ea-branch-85

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

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (21)
internal-packages/run-engine/src/engine/locking.ts (1)

183-188: Avoid double-counting lock duration on failures

Failure 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 debugging

Include 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 retryable
apps/webapp/app/runEngine/concerns/queues.server.ts (8)

48-53: Return a 404 for missing specified queue

Surface 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 version

Aligns 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 queue

Use 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 worker

Improves 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 name

Guard 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 errors

If 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 group

Match 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 structured

Stay 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 89b1d8b and 88785d4.

📒 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/metrics

Short-circuiting on ServiceValidationError here is the right call; it prevents misattributing routine failures to locking.


18-18: Import source looks correct

Importing ServiceValidationError from local errors module aligns with the new handling.


178-196: Remove name‐based fallback; instanceof is sufficient

All ServiceValidationError throw sites in run-engine import the same class from its own errors.js (no mixed definitions), so the instanceof ServiceValidationError check will always match.

apps/webapp/app/runEngine/concerns/payloads.server.ts (1)

6-6: Centralized error import

Switch to the shared ServiceValidationError is consistent with the PR’s goal.

apps/webapp/app/runEngine/concerns/queues.server.ts (1)

17-17: Centralized error import

Using the shared ServiceValidationError here keeps behavior consistent across the app.

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

32-32: Import reordering only — OK

No behavioral impact.

apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts (1)

1-1: Updated import path for EngineServiceValidationError — OK

Importing 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 as EngineServiceValidationError 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) and EngineServiceValidationError (run-engine alias) covers cross-package instanceof issues.

…espond properly

This also stops all the unnecessary error logging when throwing 
ServiceValidationErrors
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (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

📥 Commits

Reviewing files that changed from the base of the PR and between 88785d4 and d7f34c7.

📒 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)

@ericallam ericallam merged commit 2eddda1 into main Sep 12, 2025
31 checks passed
@ericallam ericallam deleted the ea-branch-85 branch September 12, 2025 13:56
Copy link

sentry-io bot commented Sep 15, 2025

Issues attributed to commits in this pull request

This pull request was merged and Sentry observed the following issues:

Did you find this useful? React with a 👍 or 👎

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.

2 participants