{"record":{"id":"cd4b807b521c3639","repo":"anomalyco/sst","slug":"the-this-name-state-already-has-a-next-state","errorCode":null,"errorMessage":"The \"${this.name}\" state already has a next state. States cannot have multiple next states.","messagePattern":"The \"(.+?)\" state already has a next state\\. States cannot have multiple next states\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"platform/src/components/aws/step-functions/state.ts","lineNumber":232,"sourceCode":"  protected _retries?: RetryArgs[];\n  protected _catches?: { next: State; props: CatchArgs }[];\n\n  constructor(protected args: StateArgs) {}\n\n  protected addChildGraph<T extends State>(state: T): T {\n    if (state._parentGraphState)\n      throw new Error(\n        `Cannot reuse the \"${state.name}\" state. States cannot be reused in Map or Parallel branches.`,\n      );\n\n    this._childGraphStates.push(state);\n    state._parentGraphState = this;\n    return state;\n  }\n\n  protected addNext<T extends State>(state: T): T {\n    if (this._nextState)\n      throw new Error(\n        `The \"${this.name}\" state already has a next state. States cannot have multiple next states.`,\n      );\n\n    this._nextState = state;\n    state._prevState = this;\n    return state;\n  }\n\n  protected addRetry(args?: RetryArgs) {\n    this._retries = this._retries || [];\n    this._retries.push({\n      errors: [\"States.ALL\"],\n      backoffRate: 2,\n      interval: \"1 second\",\n      maxAttempts: 3,\n      ...args,\n    });\n    return this;","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/platform/src/components/aws/step-functions/state.ts#L214-L250","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["For branching, wrap the alternative paths in a Parallel or Choice state instead of calling `.next()` twice on the same state.","If you need multiple downstream targets from one state, add a Choice state with `when()`/`otherwise()` pointing at the targets.","Review your chaining code for a duplicated `.next()` call on the same state object (e.g. shared variable or loop)."],"exampleFix":"// before\ntaskA.next(taskIfSuccess);\ntaskA.next(taskIfFailure);\n\n// after\nconst choice = new sst.aws.StepFunctionsChoice(\"WhichPath\");\nchoice.when($.lambda(sns.publish, ...), taskIfSuccess)\n  .otherwise(taskIfFailure);\ntaskA.next(choice);","handlingStrategy":"validation","validationCode":"function canChain(state: { _nextState?: unknown }) {\n  return !(state as { _nextState?: unknown })._nextState;\n}\nif (!canChain(taskA)) throw new Error(\"taskA already has a next state\");\ntaskA.next(taskB);","typeGuard":"function isChainable(state: object): state is object & { _nextState: undefined } {\n  return (state as { _nextState?: unknown })._nextState === undefined;\n}","tryCatchPattern":"try {\n  state.next(nextState);\n} catch (err) {\n  if (String(err).includes(\"already has a next state\")) {\n    // branch via Choice/Parallel instead of a second .next()\n  } else throw err;\n}","preventionTips":["Chain each state exactly once; build branches with Choice (`when`/`otherwise`) or Parallel instead of repeated `.next()`.","Avoid reusing the same builder variable in multiple code paths that call `.next()`.","Never call `.next()` on a state inside a loop keyed by the same source state."],"tags":["step-functions","state-machine","chaining"],"backgroundTag":"multiple-next-states","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}