# idempotency: a worked example

Canonical page: https://vibe-coding-101.brighteng.org/c/idempotency/#before-and-after

## The problem

A user wants notification emails disabled. The same request may be submitted twice. Compare a toggle with an explicit assignment to see why the operation's meaning matters before choosing a retry strategy.

## Prompt to paste

Make this handler idempotent. Use a stable operation key and test duplicate, concurrent, and crash-retried deliveries.

## Before

Toggling a preference expresses a change relative to the current state. Starting from true, one call turns emails off and the second call turns them back on.

## After

Assigning false expresses the desired state directly. Starting from true, both one call and two calls leave emails disabled. The same operation has the same intended effect when repeated.

## Run the check

Save the following code as idempotency.mjs and run `node --test idempotency.mjs` with Node.js 22.12 or later.

```js
import test from 'node:test';
import assert from 'node:assert/strict';

function before(state) {
  state.emailEnabled = !state.emailEnabled;
}

function after(state) {
  state.emailEnabled = false;
}

test('repeating the toggle reverses the requested change', () => {
  const state = { emailEnabled: true };
  before(state);
  assert.equal(state.emailEnabled, false);
  before(state);
  assert.equal(state.emailEnabled, true);
});

test('repeating the assignment preserves the desired state', () => {
  const state = { emailEnabled: true };
  after(state);
  assert.equal(state.emailEnabled, false);
  after(state);
  assert.equal(state.emailEnabled, false);
});
```

## Expected result

Two toggle calls finish with emailEnabled equal to true; two disable calls finish with it equal to false. This is a deterministic state comparison. It makes no claim about request latency, payment safety, or production duplicate rates.

## Limits

A payment cannot usually become idempotent through assignment alone. A handler may need a stable operation key, durable storage, and coordination between the side effect and its recorded result. Test simultaneous duplicates, restarts, payload mismatches, and failures at that boundary. A database transaction cannot undo a completed external API call. Use the external provider's documented duplicate-handling mechanism where available. Idempotency does not require identical response bodies or forbid logging each request.

## Sources

- [RFC 9110, section 9.2.2: Idempotent Methods](https://www.rfc-editor.org/rfc/rfc9110.html#section-9.2.2): Idempotency concerns the intended effect of repeated requests, rather than identical responses.
- [Stripe: Idempotent requests](https://docs.stripe.com/api/idempotent_requests): A concrete provider-specific operation key and replay contract; not a universal implementation recipe.

Sources checked: 2026-10-09. These are original illustrative examples with automated checks. Human editorial approval is not recorded. Policy: https://vibe-coding-101.brighteng.org/editorial/
