anomalyco/sst · error · Error

Cannot reuse the "${this.name}" state. States cannot be reus

Error message

Cannot reuse the "${this.name}" state. States cannot be reused in Map or Parallel branches.

What it means

A single State instance can appear in only one place in a Step Functions state machine graph. `State.assertStateNotReused` (platform/src/components/aws/step-functions/state.ts:309) tracks which graph (main vs each Map/Parallel branch) has visited each state object and throws when the same instance is reached from more than one graph, i.e. shared across branches.

Source

Thrown at platform/src/components/aws/step-functions/state.ts:315

    states.set(this.name, this);

    this._nextState?.assertStateNameUnique(states);
    this._catches?.forEach((c) => c.next.assertStateNameUnique(states));
    this._childGraphStates.forEach((c) => c.assertStateNameUnique(states));
  }

  /**
   * Assert that the state is not reused.
   * @internal
   */
  public assertStateNotReused(
    states: Map<State, string> = new Map(),
    graphId: string = "main",
  ) {
    const existing = states.get(this);
    if (existing && existing !== graphId)
      throw new Error(
        `Cannot reuse the "${this.name}" state. States cannot be reused in Map or Parallel branches.`,
      );

    states.set(this, graphId);

    this._nextState?.assertStateNotReused(states, graphId);
    this._catches?.forEach((c) => c.next.assertStateNotReused(states, graphId));
    this._childGraphStates.forEach((c) => {
      const childGraphId = randomBytes(16).toString("hex");
      c.assertStateNotReused(states, childGraphId);
    });
  }

  /**
   * Get the permissions required for the state.
   * @internal
   */
  public getPermissions(): FunctionPermissionArgs[] {

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Create a separate State instance per branch, even if the configuration is identical.
  2. Extract a factory function that constructs fresh states on each call instead of returning shared instances.
  3. If the logic is truly identical and reused, consider a nested state machine definition or duplicate the chain with unique names.

Example fix

// before
const notify = snsPublish.next(finalize);
parallel.branch(notify);
parallel.branch(notify);

// after
const makeNotify = (name: string) =>
  new sst.aws.StepFunctionsTask(name, { ... });
parallel.branch(makeNotify("Notify1").next(new sst.aws.StepFunctionsTask("Finalize1", { ... })));
parallel.branch(makeNotify("Notify2").next(new sst.aws.StepFunctionsTask("Finalize2", { ... })));
Defensive patterns

Strategy: validation

Validate before calling

const seen = new Set<object>();
function assertNotShared(state: object) {
  if (seen.has(state))
    throw new Error("state instance reused across branches");
  seen.add(state);
}

Type guard

null

Try / catch

try {
  parallel.branch(sharedChain);
} catch (err) {
  if (String(err).includes("Cannot reuse")) {
    // build fresh state instances per branch via a factory function
  } else throw err;
}

Prevention

When it happens

Trigger: Using the same State instance inside two different Map item selector chains or two different Parallel branches (e.g. `const shared = task.next(notify); branch1.start(shared); branch2.start(shared);`). The compile-time counterpart is `addChildGraph` throwing for a state already attached to another parent graph.

Common situations: Extracting a common 'notify'/'cleanup' chain into a variable and appending it to multiple Parallel branches or Map bodies; refactoring shared steps into a helper function that returns the same state objects for reuse.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/fb08cb9faa97ebb0. Report an issue: GitHub.