> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# cancelFlow

# cancelFlow

Cancels a flow before it has been broadcast to the blockchain. Once cancelled, the flow cannot be resumed — create a new one to start over.

## When to call

Call `cancelFlow` only when `executionState` is `initiated`, `source_attached`, `quoted`, or `signing`.

Before retrying a cancellation, call [`getFlow`](/docs/javascript/reference/client/get-flow) and check its current state.

<Warning>
  You cannot cancel a `broadcasted` or `source_confirmed` flow because funds
  have already been submitted. Poll the existing flow instead. If the state is
  already `cancelled`, `expired`, or `failed`, do not call `cancelFlow` again;
  create a new flow if the user wants another attempt. Calling from an
  unsupported state returns `409`.
</Warning>

## Usage

```javascript theme={"system"}
import { cancelFlow } from '@dynamic-labs-sdk/client';

const flow = await cancelFlow({ flowId: 'your-flow-id' });

console.log('Status:', flow.executionState); // 'cancelled'
```

## Parameters

| Parameter | Type     | Description            |
| --------- | -------- | ---------------------- |
| `flowId`  | `string` | The flow ID to cancel. |

## Returns

`Promise<Flow>` — the cancelled flow with `executionState: 'cancelled'`.

## Examples

### Cancel on user action

```javascript theme={"system"}
import { cancelFlow } from '@dynamic-labs-sdk/client';

const handleCancel = async (flowId) => {
  await cancelFlow({ flowId });
  console.log('Flow cancelled');
};
```

### Cancel on wallet rejection

If a user rejects the signing request in their wallet, cancel the flow to clean up:

```javascript theme={"system"}
import { submitFlowTransaction, cancelFlow } from '@dynamic-labs-sdk/client';

try {
  await submitFlowTransaction({
    flowId: 'your-flow-id',
    walletAccount,
  });
} catch (error) {
  const isRejected =
    error.message?.includes('rejected') ||
    error.message?.includes('denied');

  if (isRejected) {
    await cancelFlow({ flowId: 'your-flow-id' });
  }
}
```

## React

```tsx theme={"system"}
import { useCancelFlow } from '@dynamic-labs-sdk/react-hooks';

function CancelButton({ flowId }) {
  const { mutate: cancel, isPending } = useCancelFlow();

  return (
    <button onClick={() => cancel({ flowId })} disabled={isPending}>
      {isPending ? 'Cancelling...' : 'Cancel Flow'}
    </button>
  );
}
```

## Related

* [Fireblocks Flow JavaScript SDK guide](/docs/overview/fireblocks-flow-js-sdk) - End-to-end flow guide
* [`getFlow`](/docs/javascript/reference/client/get-flow) - Poll flow state
* [`submitFlowTransaction`](/docs/javascript/reference/client/submit-flow-transaction) - Submit for signing and broadcast
