Task jobs are event-driven state machines where you control the full lifecycle. Events update state and optionally schedule execution, while execute runs when the scheduled alarm fires. Unlike Continuous, there is no automatic schedule — you decide when (and whether) to run.
This is the
Task job type from @durable-effect/jobs. It is distinct from the @durable-effect/task package.Task.make(config)
Creates an unregistered task job definition. The job name is assigned later via the key you use in createDurableJobs.
TaskMakeConfig fields
Effect Schema for validating and serializing the job’s persisted state. State is durably stored in the Durable Object and survives restarts. Invalid state throws
ValidationError.Effect Schema for validating incoming events. Every event sent via
.send() is decoded against this schema before being passed to onEvent.Called for each incoming event. The validated event is passed as the first parameter — a plain value, not an Effect. The context provides state access, scheduling, and metadata.Typical responsibilities:
- Update state based on the event via
ctx.setStateorctx.updateState - Schedule the next execution via
ctx.scheduleif needed - Optionally terminate the task via
ctx.terminate
Called when the durable alarm fires. The context provides the same state access and scheduling capabilities as
onEvent.Typical responsibilities:- Process the current state
- Schedule the next execution if more work remains
- Terminate the task via
ctx.terminatewhen work is complete
Called when either
onEvent or execute completes and no alarm is scheduled. Use this to schedule delayed cleanup, log idle state, or trigger maintenance tasks. Must return Effect<void, never, never>.Optional error handler called when
onEvent or execute throws. If not provided, errors are logged and the task continues. Must return Effect<void, never, never>.Use this to log errors, track failure counts in state, schedule retries, or terminate on fatal errors.Controls the log level for this job’s internal logs.
| Value | Behavior |
|---|---|
false (default) | LogLevel.Error — only failures |
true | LogLevel.Debug — all logs |
LogLevel.Warning | Warnings and above |
LogLevel.None | Silent |
TaskEventContext<S>
The context passed to onEvent for each incoming event.
| Property | Type | Description |
|---|---|---|
state | Effect<S | null> | Current state (null if no state set yet) |
setState(s) | (s: S) => Effect<void> | Replace entire state |
updateState(fn) | (fn: (s: S) => S) => Effect<void> | Transform state (no-op if state is null) |
schedule(when) | (when) => Effect<void> | Schedule execution |
cancelSchedule() | () => Effect<void> | Cancel scheduled execution |
getScheduledTime() | () => Effect<number | null> | Get scheduled time (ms) or null |
terminate() | () => Effect<never> | Terminate the task and purge all state |
instanceId | string | Durable Object instance ID |
jobName | string | Registered job name |
executionStartedAt | number | Timestamp (ms) when this handler started |
isFirstEvent | boolean | true if state was null before this event |
eventCount | Effect<number> | Total events received |
createdAt | Effect<number> | When this task was created (ms) |
Lazily loads state from storage. Returns
null if no state has been set yet — use isFirstEvent to detect the first event without an extra yield.Persists a new state value, replacing the current one entirely.
Reads state, applies
fn, and writes the result back. No-op if state is currently null.Schedules the next
execute call. Accepts flexible time inputs — see Schedule inputs below.Cancels any pending scheduled execution. Has no effect if no alarm is set.
Returns the scheduled execution time as a Unix timestamp in milliseconds, or
null if no alarm is set.Cancels any pending alarm, deletes all state from storage, and short-circuits the current handler. No code after the
yield* runs.true when the state was null before this event arrived. Use this to initialize state on the first event without an extra yield* ctx.state check.Total number of events received by this task instance.
Unix timestamp in milliseconds of when this task instance was first created.
TaskExecuteContext<S>
The context passed to execute (and onIdle) when the alarm fires.
| Property | Type | Description |
|---|---|---|
state | Effect<S | null> | Current state (null if not set) |
setState(s) | (s: S) => Effect<void> | Replace entire state |
updateState(fn) | (fn: (s: S) => S) => Effect<void> | Transform state |
schedule(when) | (when) => Effect<void> | Schedule next execution |
cancelSchedule() | () => Effect<void> | Cancel scheduled execution |
getScheduledTime() | () => Effect<number | null> | Get scheduled time (ms) |
terminate() | () => Effect<never> | Terminate task and purge all state |
instanceId | string | Durable Object instance ID |
jobName | string | Registered job name |
executionStartedAt | number | Timestamp (ms) when this handler started |
eventCount | Effect<number> | Total events received |
executeCount | Effect<number> | Number of times execute has run (1-indexed) |
createdAt | Effect<number> | When this task was created (ms) |
TaskEventContext<S>. The additional fields are:
How many times
execute has been called for this instance. 1 on the first execution.Schedule inputs
ctx.schedule(when) accepts four forms:
