## 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](https://github.com/triggerdotdev/trigger.dev/pull/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](https://github.com/triggerdotdev/trigger.dev/pull/3491))
<details>
<summary>Raw changeset output</summary>
# Releases
## @trigger.dev/build@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## trigger.dev@4.4.6
### 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](https://github.com/triggerdotdev/trigger.dev/pull/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](https://github.com/triggerdotdev/trigger.dev/pull/3529))
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
- `@trigger.dev/build@4.4.6`
- `@trigger.dev/schema-to-json@4.4.6`
## @trigger.dev/core@4.4.6
### 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](https://github.com/triggerdotdev/trigger.dev/pull/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](https://github.com/triggerdotdev/trigger.dev/pull/3529))
## @trigger.dev/python@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
- `@trigger.dev/build@4.4.6`
- `@trigger.dev/sdk@4.4.6`
## @trigger.dev/react-hooks@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## @trigger.dev/redis-worker@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## @trigger.dev/rsc@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## @trigger.dev/schema-to-json@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## @trigger.dev/sdk@4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
</details>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@trigger.dev/schema-to-json
Convert various schema validation libraries to JSON Schema format.
Installation
npm install @trigger.dev/schema-to-json
Important: Bundle Safety
This package is designed to be bundle-safe. It does NOT bundle any schema libraries (zod, yup, etc.) as dependencies. Instead:
- Built-in conversions work immediately (ArkType, Zod 4, TypeBox)
- External conversions (Zod 3, Yup, Effect) require the conversion libraries to be available at runtime
This design ensures that:
- ✅ Your bundle size stays small
- ✅ You only include the schema libraries you actually use
- ✅ Tree-shaking works properly
- ✅ No unnecessary dependencies are installed
Supported Schema Libraries
- ✅ Zod - Full support
- Zod 4: Native support via built-in
toJsonSchemamethod (no external deps needed) - Zod 3: Requires
zod-to-json-schemato be installed
- Zod 4: Native support via built-in
- ✅ Yup - Requires
@sodaru/yup-to-json-schemato be installed - ✅ ArkType - Native support (built-in
toJsonSchemamethod) - ✅ Effect/Schema - Requires
effector@effect/schemato be installed - ✅ TypeBox - Native support (already JSON Schema compliant)
- ⏳ Valibot - Coming soon
- ⏳ Superstruct - Coming soon
- ⏳ Runtypes - Coming soon
Usage
Basic Usage (Built-in conversions only)
import { schemaToJsonSchema } from '@trigger.dev/schema-to-json';
import { type } from 'arktype';
// Works immediately for schemas with built-in conversion
const arkSchema = type({
name: 'string',
age: 'number',
});
const result = schemaToJsonSchema(arkSchema);
console.log(result);
// { jsonSchema: {...}, schemaType: 'arktype' }
Full Usage (With external conversion libraries)
import { schemaToJsonSchema, initializeSchemaConverters } from '@trigger.dev/schema-to-json';
import { z } from 'zod';
// Initialize converters once in your app (loads conversion libraries if available)
await initializeSchemaConverters();
// Now you can convert Zod 3, Yup, and Effect schemas
const zodSchema = z.object({
name: z.string(),
age: z.number(),
email: z.string().email(),
});
const result = schemaToJsonSchema(zodSchema);
console.log(result);
// {
// jsonSchema: {
// type: 'object',
// properties: {
// name: { type: 'string' },
// age: { type: 'number' },
// email: { type: 'string', format: 'email' }
// },
// required: ['name', 'age', 'email']
// },
// schemaType: 'zod'
// }
API
schemaToJsonSchema(schema, options?)
Convert a schema to JSON Schema format.
Parameters:
schema- The schema to convertoptions(optional)name- Name to use for the schema (supported by some converters)additionalProperties- Additional properties to merge into the result
Returns:
{ jsonSchema, schemaType }- The converted JSON Schema and detected typeundefined- If the schema cannot be converted
initializeSchemaConverters()
Initialize the external conversion libraries. Call this once in your application if you need to convert schemas that don't have built-in JSON Schema support (Zod 3, Yup, Effect).
Returns: Promise<void>
canConvertSchema(schema)
Check if a schema can be converted to JSON Schema.
Returns: boolean
detectSchemaType(schema)
Detect the type of schema.
Returns: 'zod' | 'yup' | 'arktype' | 'effect' | 'valibot' | 'superstruct' | 'runtypes' | 'typebox' | 'unknown'
areConvertersInitialized()
Check which conversion libraries are available.
Returns: { zod: boolean, yup: boolean, effect: boolean }
Peer Dependencies
Each schema library is an optional peer dependency. Install only the ones you need:
# For Zod
npm install zod
# For Yup
npm install yup
# For ArkType
npm install arktype
# For Effect
npm install effect @effect/schema
# For TypeBox
npm install @sinclair/typebox
License
MIT