retrysafe
← All rules

unguarded-side-effect

error

A non-idempotent effect (payment, email, plain insert, increment) runs with no dedupe guard on its path.

Why it goes wrong

Webhook providers and queues deliver at least once. A timeout, deploy, or manual resend runs the handler again with the same event, and every unguarded effect happens again.

Safe pattern

Claim the event atomically before the effect (unique insert in the same transaction as DB writes, or Redis SET NX), or pass the provider's idempotency key derived from the event id.

Configure

// retrysafe.config.ts
export default defineConfig({
  rules: { "unguarded-side-effect": "error" }, // or "off"
});

// or, for one line (a reason is required):
// retrysafe-ignore unguarded-side-effect -- <why this is safe>