durable-execution-sdk-js.durablecontext.step.md

December 2, 2025 · View on GitHub

Home > @aws/durable-execution-sdk-js > DurableContext > step

DurableContext.step() method

Executes a function as a durable step with automatic retry and state persistence

Signature:

step<TOutput>(name: string | undefined, fn: StepFunc<TOutput, TLogger>, config?: StepConfig<TOutput>): DurablePromise<TOutput>;

Parameters

Parameter

Type

Description

name

string | undefined

Step name for tracking and debugging

fn

StepFunc<TOutput, TLogger>

Function to execute as a durable step

config

StepConfig<TOutput>

(Optional) Optional configuration for retry strategy, semantics, and serialization

Returns:

DurablePromise<TOutput>

Exceptions

{StepError} When the step function fails after all retry attempts are exhausted

Remarks

**IMPORTANT**: step() is designed for single atomic operations and cannot be used to group multiple durable operations (like other steps, waits, or child contexts). The step function receives a simple StepContext (for logging only), not a full DurableContext.

**To group multiple durable operations, use runInChildContext() instead:**

// ❌ WRONG: Cannot call durable operations inside step
await context.step("process-order", async (ctx) => {
  await context.wait({ seconds: 1 });    // ERROR: context not available
  await context.step(async () => ...);   // ERROR: context not available
  return result;
});

// ✅ CORRECT: Use runInChildContext to group operations
await context.runInChildContext("process-order", async (childCtx) => {
  await childCtx.wait({ seconds: 1 });
  const step1 = await childCtx.step(async () => validateOrder(order));
  const step2 = await childCtx.step(async () => chargePayment(step1));
  return step2;
});

Example

// ✅ Good: Single atomic operation
const result = await context.step(
  "fetch-user-data",
  async (ctx) => {
    return await fetchUserFromAPI(userId);
  },
  { retryStrategy: exponentialBackoff },
);