anomalyco/sst · error · Error

The "${this.name}" state already has a next state. States ca

Error message

The "${this.name}" state already has a next state. States cannot have multiple next states.

What it means

In SST's StepFunctions component, each state can only be chained to a single successor via `.next()`. The underlying `addNext` in platform/src/components/aws/step-functions/state.ts:230 throws when you call `.next()` on a state whose `_nextState` is already set, because Step Functions state machines (in this chain-style builder) model a linear `Next` transition, not a branching one.

Source

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

  protected _retries?: RetryArgs[];
  protected _catches?: { next: State; props: CatchArgs }[];

  constructor(protected args: StateArgs) {}

  protected addChildGraph<T extends State>(state: T): T {
    if (state._parentGraphState)
      throw new Error(
        `Cannot reuse the "${state.name}" state. States cannot be reused in Map or Parallel branches.`,
      );

    this._childGraphStates.push(state);
    state._parentGraphState = this;
    return state;
  }

  protected addNext<T extends State>(state: T): T {
    if (this._nextState)
      throw new Error(
        `The "${this.name}" state already has a next state. States cannot have multiple next states.`,
      );

    this._nextState = state;
    state._prevState = this;
    return state;
  }

  protected addRetry(args?: RetryArgs) {
    this._retries = this._retries || [];
    this._retries.push({
      errors: ["States.ALL"],
      backoffRate: 2,
      interval: "1 second",
      maxAttempts: 3,
      ...args,
    });
    return this;

View on GitHub (pinned to a0bd20f762)

Solutions

  1. For branching, wrap the alternative paths in a Parallel or Choice state instead of calling `.next()` twice on the same state.
  2. If you need multiple downstream targets from one state, add a Choice state with `when()`/`otherwise()` pointing at the targets.
  3. Review your chaining code for a duplicated `.next()` call on the same state object (e.g. shared variable or loop).

Example fix

// before
taskA.next(taskIfSuccess);
taskA.next(taskIfFailure);

// after
const choice = new sst.aws.StepFunctionsChoice("WhichPath");
choice.when($.lambda(sns.publish, ...), taskIfSuccess)
  .otherwise(taskIfFailure);
taskA.next(choice);
Defensive patterns

Strategy: validation

Validate before calling

function canChain(state: { _nextState?: unknown }) {
  return !(state as { _nextState?: unknown })._nextState;
}
if (!canChain(taskA)) throw new Error("taskA already has a next state");
taskA.next(taskB);

Type guard

function isChainable(state: object): state is object & { _nextState: undefined } {
  return (state as { _nextState?: unknown })._nextState === undefined;
}

Try / catch

try {
  state.next(nextState);
} catch (err) {
  if (String(err).includes("already has a next state")) {
    // branch via Choice/Parallel instead of a second .next()
  } else throw err;
}

Prevention

When it happens

Trigger: Calling `.next()` twice on the same State instance, e.g. `const s = task1.next(task2); s.next(task3);`. Also happens when a state variable is chained in two different code paths (e.g. both branches of an if/else call `.next()` on the same state object), or when a Catch target state is also chained as the Next state of the same state.

Common situations: Developers wiring conditional-looking logic by chaining the same start state to two different states, reusing a builder variable, or accidentally calling `.next()` inside a loop that iterates over the same source state.

Related errors


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