## Summary
5 improvements, 5 bug fixes.
## Improvements
- Add `node-24` and `node-26` as supported `runtime` options in
`trigger.config.ts`. The `experimental-node-24` and
`experimental-node-26` names are now deprecated aliases and emit a
deprecation warning; switch to `node-24` / `node-26` instead.
([#4337](#4337))
```ts
import { defineConfig } from "@trigger.dev/sdk";
export default defineConfig({
runtime: "node-24",
project: "<your-project-ref>",
});
```
- Avoid logging task run environment variable values at debug level
([#4336](#4336))
- Custom chat agent loops get two ergonomic wins for owning the turn
loop. ([#4304](#4304))
`chat.writeTurnComplete()` now returns the turn boundary's resume
cursors (`lastEventId` for the output stream and `sessionInEventId` for
the input stream), so you can persist them straight from the task
instead of round-tripping them back from the client.
```ts
const { lastEventId, sessionInEventId } = await
chat.writeTurnComplete();
await db.chats.update(chatId, { lastEventId, sessionInEventId });
```
`chat.pipeAndCapture()` no longer throws when a stream is stopped or
fails. It now returns a `PipeAndCaptureResult` whose `message` holds any
partial output captured before the stop or failure, alongside a typed
`status` (`"complete" | "aborted" | "error"`) and, on failure, the
`error`. Read the message off the result:
```ts
const { message, status, error } = await chat.pipeAndCapture(result, {
signal,
});
if (message) conversation.addResponse(message);
if (status === "error") logger.error("turn failed", { error });
```
Note: `pipeAndCapture` previously resolved to `UIMessage | undefined`.
Update call sites to read `.message` from the returned result.
- Suppress a build-time warning that could appear in Vite-based projects
when the optional `@ai-sdk/otel` package is not installed.
([#4188](#4188))
## Bug fixes
- Fixes intermittent `trigger dev` run crashes where a run could fail at
boot with a cryptic `Cannot find module .../dev-run-worker.mjs` after a
rebuild had cleaned up the build directory the run was launched against.
Dev runs now retry cleanly instead of hard-crashing when their build
directory is missing, the dev watchdog no longer removes the build tree
of a still-running session, and a run assigned to a worker version that
was superseded by a rebuild now fails fast with a clear message instead
of silently hanging until it times out.
([#4276](#4276))
## Server changes
These changes affect the self-hosted Docker image and Trigger.dev Cloud:
- Refreshed the side menu: separate organization and account menus, a
new project switcher, and the menu is now resizable by dragging its
edge. The account Profile page has also been redesigned.
([#4066](#4066))
- Allow different organization members to use the same development
branch name without sharing or colliding with each other's branch
environments.
([#4323](#4323))
- Limit account settings email input to 254 characters.
([#4330](#4330))
- Prevent duplicate Staging and Preview environments when account setup
requests overlap
([#4261](#4261))
- Fix the docs link on the empty Prompts page, which pointed to a page
that no longer exists.
([#4247](#4247))
<details>
<summary>Raw changeset output</summary>
# Releases
## @trigger.dev/build@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
## trigger.dev@4.5.7
### Patch Changes
- Fixes intermittent `trigger dev` run crashes where a run could fail at
boot with a cryptic `Cannot find module .../dev-run-worker.mjs` after a
rebuild had cleaned up the build directory the run was launched against.
Dev runs now retry cleanly instead of hard-crashing when their build
directory is missing, the dev watchdog no longer removes the build tree
of a still-running session, and a run assigned to a worker version that
was superseded by a rebuild now fails fast with a clear message instead
of silently hanging until it times out.
([#4276](#4276))
- Add `node-24` and `node-26` as supported `runtime` options in
`trigger.config.ts`. The `experimental-node-24` and
`experimental-node-26` names are now deprecated aliases and emit a
deprecation warning; switch to `node-24` / `node-26` instead.
([#4337](#4337))
```ts
import { defineConfig } from "@trigger.dev/sdk";
export default defineConfig({
runtime: "node-24",
project: "<your-project-ref>",
});
```
- Avoid logging task run environment variable values at debug level
([#4336](#4336))
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
- `@trigger.dev/build@4.5.7`
- `@trigger.dev/schema-to-json@4.5.7`
## @trigger.dev/core@4.5.7
### Patch Changes
- Add `node-24` and `node-26` as supported `runtime` options in
`trigger.config.ts`. The `experimental-node-24` and
`experimental-node-26` names are now deprecated aliases and emit a
deprecation warning; switch to `node-24` / `node-26` instead.
([#4337](#4337))
```ts
import { defineConfig } from "@trigger.dev/sdk";
export default defineConfig({
runtime: "node-24",
project: "<your-project-ref>",
});
```
## @trigger.dev/python@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/sdk@4.5.7`
- `@trigger.dev/core@4.5.7`
- `@trigger.dev/build@4.5.7`
## @trigger.dev/react-hooks@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
## @trigger.dev/redis-worker@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
## @trigger.dev/rsc@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
## @trigger.dev/schema-to-json@4.5.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
## @trigger.dev/sdk@4.5.7
### Patch Changes
- Custom chat agent loops get two ergonomic wins for owning the turn
loop. ([#4304](#4304))
`chat.writeTurnComplete()` now returns the turn boundary's resume
cursors (`lastEventId` for the output stream and `sessionInEventId` for
the input stream), so you can persist them straight from the task
instead of round-tripping them back from the client.
```ts
const { lastEventId, sessionInEventId } = await
chat.writeTurnComplete();
await db.chats.update(chatId, { lastEventId, sessionInEventId });
```
`chat.pipeAndCapture()` no longer throws when a stream is stopped or
fails. It now returns a `PipeAndCaptureResult` whose `message` holds any
partial output captured before the stop or failure, alongside a typed
`status` (`"complete" | "aborted" | "error"`) and, on failure, the
`error`. Read the message off the result:
```ts
const { message, status, error } = await chat.pipeAndCapture(result, {
signal,
});
if (message) conversation.addResponse(message);
if (status === "error") logger.error("turn failed", { error });
```
Note: `pipeAndCapture` previously resolved to `UIMessage | undefined`.
Update call sites to read `.message` from the returned result.
- Suppress a build-time warning that could appear in Vite-based projects
when the optional `@ai-sdk/otel` package is not installed.
([#4188](#4188))
- Updated dependencies:
- `@trigger.dev/core@4.5.7`
</details>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fixes TRI-12078
Summary
Prevents concurrent environment setup requests from creating duplicate Staging and Preview environments.
Fix
Adds database-enforced uniqueness for root Staging and Preview environments.
If two requests race, the losing request loads the environment created by the winner and continues successfully instead of creating a duplicate or returning an error.