Tags: triggerdotdev/trigger.dev
Tags
refactor(supervisor): op + kind first-class on State
feat(supervisor): wide events on snapshot lifecycle
fix(supervisor): wide-event review fixes + noisy-routes flag + socket… … lifecycle
fix(webapp): dedupe realtimeStreams array push on stream create The PUT handler unconditionally appended streamId to TaskRun.realtimeStreams on every call, so repeat inits for the same (run, streamId) hot-looped a row UPDATE and bloated the array. Read first and only push when the streamId isn't already present, matching the existing append handler.
chore: release v4.4.6 (#3501) ## Summary 1 improvement, 1 bug fix. ## Improvements - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## Bug fixes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) <details> <summary>Raw changeset output</summary> # Releases ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## [email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
chore: release v4.4.6 (#3501) ## Summary 1 improvement, 1 bug fix. ## Improvements - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## Bug fixes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) <details> <summary>Raw changeset output</summary> # Releases ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## [email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
chore: release v4.4.6 (#3501) ## Summary 1 improvement, 1 bug fix. ## Improvements - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## Bug fixes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) <details> <summary>Raw changeset output</summary> # Releases ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## [email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Fix dev workers spinning at 100% CPU after the parent CLI disconnects. Orphaned `trigger-dev-run-worker` (and indexer) processes were caught in an `uncaughtException` feedback loop: a periodic IPC send via `process.send` would throw `ERR_IPC_CHANNEL_CLOSED` once the parent closed the channel, which re-entered the same handler that itself called `process.send`, scheduled via `setImmediate` and amplified by source-map-support's `prepareStackTrace`. Fixed by (1) silently dropping packets in `ZodIpcConnection` when the channel is disconnected, (2) adding a `process.on("disconnect", ...)` handler in dev workers so they exit cleanly when the CLI closes the IPC channel, and (3) wrapping all `uncaughtException`-path `process.send` calls in a `safeSend` guard that checks `process.connected` and swallows synchronous throws. ([#3491](#3491)) - Fail attempts on uncaught exceptions instead of hanging to `MAX_DURATION_EXCEEDED`. A Node `EventEmitter` (e.g. `node-redis`) emitting `"error"` with no `.on("error", ...)` listener escalates to `uncaughtException`, which the worker previously reported but did not act on — runs drifted to maxDuration with empty attempts. They now fail fast with the original error and status `FAILED`, and respect the task's normal retry policy. You should still attach `.on("error", ...)` listeners to long-lived clients to handle errors gracefully. ([#3529](#3529)) ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` ## @trigger.dev/[email protected] ### Patch Changes - Updated dependencies: - `@trigger.dev/[email protected]` </details> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
fix(cli): fail attempt on uncaught exception instead of hanging to ma… …xDuration (TRI-9117) (#3529) When a Node EventEmitter (e.g. node-redis) emits an "error" event with no listener attached, Node escalates it to process.on("uncaughtException") in the task worker. The worker reported the error via the UNCAUGHT_EXCEPTION IPC event but did not exit, and the supervisor-side handler in taskRunProcess only logged the message at debug level — leaving the run() promise orphaned until maxDuration fired and producing empty attempts (durationMs=0, costInCents=0). The supervisor now rejects the in-flight attempt with an UncaughtExceptionError and gracefully terminates the worker (preserving the OTEL flush window) on UNCAUGHT_EXCEPTION. The attempt fails fast with TASK_EXECUTION_FAILED, surfacing the original error name, message, and stack trace, and falls under the normal retry policy. This mirrors the existing indexing-side behavior in indexWorkerManifest. Apply the same handling to unhandled promise rejections, which Node already routes through uncaughtException by default.
fix(cli): fail attempt on uncaught exception instead of hanging to ma… …xDuration (TRI-9117) (#3529) When a Node EventEmitter (e.g. node-redis) emits an "error" event with no listener attached, Node escalates it to process.on("uncaughtException") in the task worker. The worker reported the error via the UNCAUGHT_EXCEPTION IPC event but did not exit, and the supervisor-side handler in taskRunProcess only logged the message at debug level — leaving the run() promise orphaned until maxDuration fired and producing empty attempts (durationMs=0, costInCents=0). The supervisor now rejects the in-flight attempt with an UncaughtExceptionError and gracefully terminates the worker (preserving the OTEL flush window) on UNCAUGHT_EXCEPTION. The attempt fails fast with TASK_EXECUTION_FAILED, surfacing the original error name, message, and stack trace, and falls under the normal retry policy. This mirrors the existing indexing-side behavior in indexWorkerManifest. Apply the same handling to unhandled promise rejections, which Node already routes through uncaughtException by default.
fix: sync declarative schedules on deployment rollback (#3468) ## ✅ Checklist - [x] I have followed every step in the [contributing guide](https://github.com/triggerdotdev/trigger.dev/blob/main/CONTRIBUTING.md) - [x] The PR title follows the convention. - [x] I ran and tested the code works --- ## Testing - Reviewed the code flow for deployment rollback (`ChangeCurrentDeploymentService`) and confirmed it was missing schedule sync - Verified all 4 callers of `ChangeCurrentDeploymentService` (UI rollback, UI promote, API promote, finalize deployment) are now covered - Ran `pnpm run typecheck --filter webapp` — passes cleanly --- ## Changelog When rolling back (or manually promoting) a deployment, declarative schedules were not being synced to match the target deployment's worker metadata. Schedules remained as configured by the most recent deployment rather than reflecting the target version's schedule configuration. This fix adds a call to `syncDeclarativeSchedules` in `ChangeCurrentDeploymentService` after the deployment promotion is updated. It parses the target deployment's stored `BackgroundWorkerMetadata` to restore the correct schedule state. This covers both rollback and promote paths (UI and API). Errors are handled gracefully so they don't block the deployment change itself. --- ## Screenshots N/A — backend-only change. 💯 Link to Devin session: https://app.devin.ai/sessions/0debf012b58c4132be778f8ea88cd2b6 --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: nick <[email protected]>
PreviousNext