---
title: <Saga>
description: Forward steps with compensations run in reverse on failure.
---

```ts
import { Saga } from "smithers-orchestrator";

type SagaStepDef = {
  id: string;
  action: ReactElement;
  compensation: ReactElement;
  label?: string;
};

type SagaProps = {
  id?: string;
  steps?: SagaStepDef[]; // takes priority over children
  onFailure?: "compensate" | "compensate-and-fail" | "fail"; // default "compensate"
  skipIf?: boolean;
  children?: React.ReactNode; // alternative: <Saga.Step> children
};
```

```tsx
<Workflow name="deploy-saga">
  <Saga
    id="deploy"
    steps={[
      {
        id: "create-pr",
        action: <Task id="create-pr" output={outputs.pr} agent={codeAgent}>Create a PR.</Task>,
        compensation: <Task id="close-pr" output={outputs.closePr} agent={codeAgent}>Close the PR.</Task>,
      },
      {
        id: "deploy-staging",
        action: <Task id="deploy-staging" output={outputs.staging} agent={deployAgent}>Deploy staging.</Task>,
        compensation: <Task id="rollback-staging" output={outputs.rollbackStaging} agent={deployAgent}>Rollback staging.</Task>,
      },
    ]}
  />
</Workflow>
```

## Notes

- Steps run sequentially; compensations run in reverse from the failed step.
- Compensations should be idempotent, and each one **must actually undo its step's action**; a stubbed or inert compensation yields a green run with dirty state on rollback.
- `steps` and `<Saga.Step>` children are mutually exclusive; `steps` wins if both are given.
- `SagaStep` is a named export (`import { SagaStep }`) and is the same marker as `<Saga.Step>`.
