Rulesnorthwind-webhook-no-idempotency

northwind-webhook-no-idempotency

warning

northwind/reliability/webhook-no-idempotency

Docs page ↗

The handler performs a side effect — crediting a balance, sending an email, incrementing a counter — without first recording event.id, so Northwind’s automatic redelivery runs it again.

12

codebases affected, of 58

21%

of everything we scanned

no docs fix scored yet

0

docs commits aimed at this

Where it’s failing

Webhook handler mutates state without deduplicating on event.id.

what we find

what we change it to

const event = northwind.webhooks.constructEvent(req.body, sig, secret)
if (event.type === 'charge.succeeded') {
await credits.add(event.data.customer, event.data.amount)
}
res.sendStatus(200) // a retried delivery credits them again
const event = northwind.webhooks.constructEvent(req.body, sig, secret)
const claimed = await db.query(
'insert into processed_events (id) values ($1) on conflict do nothing',
[event.id],
)
if (claimed.rowCount === 0) return res.sendStatus(200) // already handled
if (event.type === 'charge.succeeded') {
await credits.add(event.data.customer, event.data.amount)
}
res.sendStatus(200)

Record event.id in a table with a unique constraint (INSERT ... ON CONFLICT DO NOTHING) and return 200 immediately when the insert affects no rows, before running any side effect.

Metadata

Category
reliability
Type
suggestion
Severity
warning
Recommended
yes
Languages
javascriptpython

Live telemetry

12 / 58 scans

Fired in 21% of scanned codebases.

After every docs commit

No docs commits target this rule yet. When one merges, the next weeks of scans re-score it here.

A fix for your docs page

Wherever this rule fires, a page on your docs site taught it. api-doctor writes the edit and opens it as a pull request on your docs repo — you review and merge.

No fix yet

Draft a docs fix for this rule

api-doctor writes the docs change from the fire pattern — you review it