serialization-failed

This error occurs when you try to pass non-serializable data between execution boundaries in your workflow. All data passed between workflow functions, step functions, and the workflow runtime must be serializable to persist in the event log.

Error message

Failed to serialize workflow arguments. Ensure you're passing serializable types
(plain objects, arrays, primitives, Date, RegExp, Map, Set).

This error can appear when:

  • Serializing workflow arguments when calling start()
  • Serializing workflow return values
  • Serializing step arguments
  • Serializing step return values

Where the error surfaces

Where you observe the failure depends on which boundary it crosses:

  • Workflow arguments: start() throws synchronously in your application code.
  • Step arguments and step return values: the step fails with the SerializationError, exactly like a step whose body threw a fatal error: no retries (the failure is deterministic), and a try/catch around the step call in your workflow code observes it. The step's recorded input shows [input unavailable: step argument serialization failed] when the arguments were the unserializable part.
  • Workflow return values: the workflow body has already returned, so nothing can catch it; the run fails.
async function stepWithBadArguments(value: unknown) {
  "use step";
  return value;
}

export async function processWorkflow(someValue: unknown) {
  "use workflow";

  try {
    await stepWithBadArguments(someValue);
  } catch (err) {
    // err.name === "SerializationError"
    // "Failed to serialize step arguments at path ..."
  }
}

Uncaught, the error propagates out of the workflow body and the run fails immediately with the error code USER_ERROR; it does not retry.

Why this happens

Workflows persist their state using an event log. Every value that crosses execution boundaries must be:

  1. Serialized to be stored in the event log
  2. Deserialized when the workflow resumes

Functions, class instances, symbols, and other non-serializable types cannot be properly reconstructed after serialization, which would break workflow replay.

Common causes

Passing functions

// Error - functions cannot be serialized
export async function processWorkflow() {
  "use workflow";

  const callback = () => console.log("done");
  await processStep(callback); // Error!
}

Solution: Pass data instead, then define the function logic in the step.

// Fixed - pass configuration data instead
export async function processWorkflow() {
  "use workflow";

  await processStep({ shouldLog: true });
}

async function processStep(config: { shouldLog: boolean }) {
  "use step";

  if (config.shouldLog) {
    console.log("done");
  }
}

Class instances

class User {
  constructor(public name: string) {}
  greet() { return `Hello ${this.name}`; }
}

// Error - class instances lose methods after serialization
export async function greetWorkflow() {
  "use workflow";

  await greetStep(new User("Alice")); // Error!
}

Solution: Pass plain objects and reconstruct the class in the step.

class User {
  constructor(public name: string) {}
  greet() { return `Hello ${this.name}`; }
}

// Fixed - pass plain object, reconstruct in step
export async function greetWorkflow() {
  "use workflow";

  await greetStep({ name: "Alice" });
}

async function greetStep(userData: { name: string }) {
  "use step";

  const user = new User(userData.name);
  console.log(user.greet());
}

Supported serializable types

Workflow SDK supports these types across execution boundaries:

Standard JSON types

  • string, number, boolean, null
  • Arrays of serializable values
  • Plain objects with serializable values

To learn more about supported types, see the Serialization section.

Debugging serialization issues

To identify what's causing serialization to fail:

  1. Check the error stack trace: It often shows which property failed.
  2. Simplify your data: Temporarily pass smaller objects to isolate the issue.
  3. Use supported data types: See Serialization for details.