Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Workflow unstable

Defines typed durable workflows.

A Workflow has a stable tag, schemas for payload, success, and failure, and an idempotency key used to derive execution ids. Workflow definitions can be executed, discarded, polled, interrupted, resumed, and registered with a handler layer. This module also includes workflow result types, compensation and cleanup helpers, suspension support, and settings for defect capture or failure suspension.

27 exports Since v4.0.0 Source

Compensation

Since v4.0.0

Adds compensation logic to an effect inside a Workflow.

When to use

Use when a top-level workflow step needs compensating cleanup if the overall workflow later fails after the step succeeds.

Details

The compensation finalizer is called if the entire workflow fails, allowing you to perform cleanup or other actions based on the success value and the cause of the workflow failure.

Gotchas

Compensation finalizers are only registered for top-level effects in the workflow and do not work for nested activities.

Signature

declare const withCompensation: {
<A, R2>(compensation: (value: A, cause: Cause<unknown>) => Effect<void, never, R2>): <E, R>(effect: Effect<A, E, R>) => Effect<A, E, Scope | WorkflowInstance | R2 | R>;
<A, E, R, R2>(effect: Effect<A, E, R>, compensation: (value: A, cause: Cause<unknown>) => Effect<void, never, R2>): Effect<A, E, Scope | WorkflowInstance | R | R2>;
}

Constructors

make

unstable
Since v4.0.0

Creates a durable workflow definition with schemas, annotations, and deterministic execution IDs derived from the workflow tag and idempotency key.

Signature

declare function make<Tag extends string, Payload extends Fields | AnyStructSchema, Success extends Top = Void, Error extends Top = Never>(tag: Tag, options: {
readonly annotations?: Context<never>;
readonly error?: Error;
readonly idempotencyKey: (payload: Payload extends Fields ? View<Payload, "Type", TypeOptionalKeys<Payload>, TypeMutableKeys<Payload>> : Payload["Type"]) => string;
readonly payload: Payload;
readonly success?: Success;
readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
}): Workflow<Tag, Payload extends Fields ? Struct<Payload> : Payload, Success, Error>

Converting

intoResult

unstable
Since v4.0.0

Runs an effect as a workflow execution and converts its outcome into a Result, handling suspension, defect capture, interruption, and workflow scope finalization.

Signature

declare function intoResult<A, E, R>(effect: Effect<A, E, R>): Effect<Result<A, E>, never, WorkflowInstance | Exclude<R, Scope>>

Guards

isResult

unstable
Since v4.0.0

Returns true when a value is a workflow Result.

Signature

declare function isResult<A = unknown, E = unknown>(u: unknown): u is Result<A, E>

Interruption

suspend

unstable
Since v4.0.0

Marks a workflow instance as suspended and interrupts the current fiber to stop execution until it is resumed.

Signature

declare function suspend(instance: {
abandoned: boolean;
readonly activityState: {
count: number;
readonly latch: Latch;
};
readonly awaitedDeferreds: Map<string, number>;
cause: Cause<never> | undefined;
readonly completedDeferreds: Set<string>;
readonly executionId: string;
failed: boolean;
interrupted: boolean;
readonly scope: Closeable;
suspended: boolean;
readonly workflow: Any;
}): Effect<never>

Models

Any

interface unstable
Since v4.0.0

Type-erased workflow shape for APIs that operate on workflows without preserving their specific payload, success, or error types.

Signature

interface Any {
constructor(_: never);
readonly _tag: string;
readonly "~effect/workflow/Workflow": "~effect/workflow/Workflow";
readonly annotations: Context<never>;
readonly errorSchema: Top;
readonly executionId: (payload: any) => Effect<string>;
readonly idempotencyKey: (payload: any) => string;
readonly payloadSchema: AnyStructSchema;
readonly successSchema: Top;
readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
}

AnyWithProps

interface unstable
Since v4.0.0

Type-erased workflow shape that also exposes executable operations needed by workflow proxy and engine helpers.

Signature

interface AnyWithProps extends Any {
constructor(_: never);
readonly errorSchema: Top;
readonly execute: (payload: any, options?: {
readonly detached?: boolean;
readonly discard?: boolean;
}) => Effect<any, any, any>;
readonly payloadSchema: AnyStructSchema;
readonly resume: (executionId: string) => Effect<void, never, WorkflowEngine>;
readonly successSchema: Top;
}

Complete

unstable
Since v4.0.0

Represents a completed workflow execution with its success or failure Exit.

Signature

declare class Complete<A, E> extends Readonly<{
readonly exit: Exit<A, E>;
}> & {
readonly _tag: "Complete";
} & Pipeable {
constructor<A, E>(args: {
readonly exit: Exit<A, E>;
});
readonly "~effect/workflow/Workflow/Result": "~effect/workflow/Workflow/Result";
static Schema<Success extends Constraint, Error extends Constraint>(options: {
readonly error: Error;
readonly success: Success;
}): CompleteSchema<Success, Error>;
}

CompleteEncoded

interface unstable
Since v4.0.0

Encoded representation of a completed workflow result containing an encoded Exit.

Signature

interface CompleteEncoded<A, E> {
readonly _tag: "Complete";
readonly exit: ExitEncoded<A, E>;
}

Result

type unstable
Since v4.0.0

Result of a workflow execution, either a completed exit or a suspended workflow state.

Signature

type Result<A, E> = Complete<A, E> | Suspended

ResultEncoded

type unstable
Since v4.0.0

Encoded representation of a workflow Result.

Signature

type ResultEncoded<A, E> = CompleteEncoded<A, E> | typeof Suspended.Encoded

Workflow

interface unstable
Since v4.0.0

Durable workflow definition with typed payload, success, and error schemas plus operations for execution, polling, interruption, resumption, and registration.

Signature

interface Workflow<Tag extends string, Payload extends AnyStructSchema, Success extends Schema.Top, Error extends Schema.Top> {
constructor(_: never);
readonly _tag: Tag;
readonly "~effect/workflow/Workflow": "~effect/workflow/Workflow";
readonly annotations: Context<never>;
readonly errorSchema: Error;
readonly execute: <Discard extends boolean = false>(payload: Payload["~type.make.in"], options?: {
readonly detached?: [Discard] extends [true] ? boolean | undefined : undefined;
readonly discard?: Discard;
}) => Effect<Discard extends true ? string : Success["Type"], Discard extends true ? never : Error["Type"], WorkflowEngine | Payload["EncodingServices"] | Success["DecodingServices"] | Error["DecodingServices"]>;
readonly executionId: (payload: Payload["~type.make.in"]) => Effect<string>;
readonly idempotencyKey: (payload: Payload["Type"]) => string;
readonly interrupt: (executionId: string) => Effect<void, never, WorkflowEngine>;
readonly payloadSchema: Payload;
readonly poll: (executionId: string) => Effect<Option<Result<Success["Type"], Error["Type"]>>, never, WorkflowEngine | Success["DecodingServices"] | Error["DecodingServices"]>;
readonly resume: (executionId: string) => Effect<void, never, WorkflowEngine>;
readonly successSchema: Success;
readonly suspendedRetrySchedule?: Schedule<any, unknown, never, never>;
readonly toLayer: <R>(execute: (payload: Payload["Type"], executionId: string) => Effect<Success["Type"], Error["Type"], R>) => Layer<never, never, WorkflowEngine | Payload["EncodingServices"] | Success["DecodingServices"] | Error["DecodingServices"] | Exclude<R, Scope | WorkflowEngine | WorkflowInstance | Execution<Tag>> | Payload["DecodingServices"] | Success["EncodingServices"] | Error["EncodingServices"]>;
readonly withCompensation: {
<A, R2>(compensation: (value: A, cause: Cause<Error["Type"]>) => Effect<void, never, R2>): <E, R>(effect: Effect<A, E, R>) => Effect<A, E, Scope | WorkflowInstance | Execution<Tag> | R2 | R>;
<A, E, R, R2>(effect: Effect<A, E, R>, compensation: (value: A, cause: Cause<Error["Type"]>) => Effect<void, never, R2>): Effect<A, E, Scope | WorkflowInstance | Execution<Tag> | R | R2>;
};
annotate<I, S>(key: Key<I, S>, value: S): Workflow<Tag, Payload, Success, Error>;
annotateMerge<I>(annotations: Context<I>): Workflow<Tag, Payload, Success, Error>;
}

Resource Management

Since v4.0.0

Adds an exit finalizer to the current workflow scope, preserving the services available when the finalizer is registered.

Details

Body-level Effect.onExit finalizers cannot observe a deposited workflow interrupt. Use this function for terminal-state work that must observe it. Finalizers are skipped when a cluster owner abandons a run attempt for replay; owner-local scope finalizers registered with provideScope still run.

Signature

declare const addFinalizer: <R>(f: (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<void, never, R>) => Effect.Effect<void, never, WorkflowInstance | R>
Since v4.0.0

Provides the workflow scope to the given effect, and closes the scope only when the workflow execution fully completes.

Signature

declare function provideScope<A, E, R>(effect: Effect<A, E, R>): Effect<A, E, WorkflowInstance | Exclude<R, Scope>>

scope

unstable
Since v4.0.0

Accesses the workflow scope, which is only closed when the workflow execution fully completes.

Signature

declare const scope: Effect.Effect<Scope.Scope, never, WorkflowInstance>
Since v4.0.0

Wraps an activity-like effect so workflow suspension waits for currently running activities to finish or suspend.

Signature

declare function wrapActivityResult<A, E, R>(effect: Effect<A, E, R>, isSuspend: (value: A) => boolean): Effect<A, E, WorkflowInstance | R>

Schemas

AnyStructSchema

interface unstable
Since v4.0.0

Schema constraint for workflow payload schemas that expose struct fields.

Signature

interface AnyStructSchema extends Top {
constructor(_: never);
readonly fields: Fields;
}

CompleteSchema

interface unstable
Since v4.0.0

Schema constructor for Complete workflow results using the supplied success and error schemas.

Signature

interface CompleteSchema<Success extends Schema.Constraint, Error extends Schema.Constraint> extends declareConstructor<Complete<Success["Type"], Error["Type"]>, Complete<Success["Encoded"], Error["Encoded"]>, readonly [Schema.Exit<Success, Error, Schema.Defect>]> {
constructor(_: never);
readonly error: Error;
readonly success: Success;
}

Result

unstable
Since v4.0.0

Creates a schema for workflow results using the supplied success and error schemas.

Signature

declare const Result: <Success extends Constraint, Error extends Constraint>(options: {
readonly error: Error;
readonly success: Success;
}) => Union<readonly [CompleteSchema<Success, Error>, typeof Suspended]>
Since v4.0.0

Schema for encoded workflow results with generic success and error payloads.

Signature

declare const ResultEncoded: Codec<ResultEncoded<any, any>, ResultEncoded<any, any>, never, never>

Suspended

unstable
Since v4.0.0

Represents a suspended workflow execution, optionally carrying the cause that triggered suspension.

Details

failed marks this execution's own SuspendOnFailure and requires explicit resume or interrupt. Inherited child failures do not set it.

Signature

declare class Suspended extends {
readonly _tag: "Suspended";
readonly cause?: Cause<never>;
readonly failed?: boolean;
} {
constructor(...args: [props?: {
readonly _tag?: "Suspended";
readonly cause?: Cause<never>;
readonly failed?: boolean;
}, options?: MakeOptions]);
readonly "~effect/workflow/Workflow/Result": "~effect/workflow/Workflow/Result";
}

Services

Since v4.0.0

Captures defects for a workflow and includes them in the result of the workflow or its activities.

Details

By default, this annotation is set to true, meaning defects are captured.

Signature

declare const CaptureDefects: Reference<boolean>
Since v4.0.0

Marks a workflow to suspend when it encounters any error.

Details

The suspended execution can later be resumed with the workflow's resume method, for example MyWorkflow.resume(executionId).

Signature

declare const SuspendOnFailure: Reference<boolean>

Utility Types

Execution

interface unstable
Since v4.0.0

Type-level marker for services associated with a specific workflow execution tag.

Signature

interface Execution<Tag extends string> {
readonly _: typeof _;
readonly _tag: Tag;
}

PayloadSchema

type unstable
Since v4.0.0

Extracts the payload schema from a Workflow.

Signature

type PayloadSchema<W> = W extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload : never

RequirementsClient

type unstable
Since v4.0.0

Computes the schema services required by clients that execute or poll workflows.

Signature

type RequirementsClient<Workflows extends Any> = Workflows extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload["EncodingServices"] | _Success["DecodingServices"] | _Error["DecodingServices"] : never

RequirementsHandler

type unstable
Since v4.0.0

Computes the schema services required by handlers that decode workflow payloads and encode workflow results.

Signature

type RequirementsHandler<Workflows extends Any> = Workflows extends Workflow<infer _Name, infer _Payload, infer _Success, infer _Error> ? _Payload["DecodingServices"] | _Payload["EncodingServices"] | _Success["DecodingServices"] | _Success["EncodingServices"] | _Error["DecodingServices"] | _Error["EncodingServices"] : never