Problem
The notify:<slug> KV state key (lastNotifiedAt, pending, total) is deleted only when the link is deleted (deleteLink in server/utils/link-store.ts). Editing a link to remove its notifyUrl leaves the state key behind. If notifications are later re-enabled on the same slug, counters resume from the old total, and a very old lastNotifiedAt causes an immediate (possibly batched) push.
Related smaller issue in the same state machine: KV.get(key, { type: 'json' }).catch(() => null) conflates a transient KV read error with corrupt state — a momentary read blip resets lifetime counters to zero on the next write.
Suggested fix
- In the edit flow (
mergeEditableLink or edit.put.ts), when notifyUrl transitions from set → unset, delete notify:<slug>.
- Optionally distinguish parse errors from read errors (
KV.get(key, 'text') + explicit JSON.parse in its own try) so transient blips don't reset counters.
Low severity: counters are cosmetic and best-effort by design.
Flagged by the final whole-branch review of the scan-notifications feature (shipped in 615f972..e59b76c).
Problem
The
notify:<slug>KV state key (lastNotifiedAt,pending,total) is deleted only when the link is deleted (deleteLinkinserver/utils/link-store.ts). Editing a link to remove itsnotifyUrlleaves the state key behind. If notifications are later re-enabled on the same slug, counters resume from the oldtotal, and a very oldlastNotifiedAtcauses an immediate (possibly batched) push.Related smaller issue in the same state machine:
KV.get(key, { type: 'json' }).catch(() => null)conflates a transient KV read error with corrupt state — a momentary read blip resets lifetime counters to zero on the next write.Suggested fix
mergeEditableLinkoredit.put.ts), whennotifyUrltransitions from set → unset, deletenotify:<slug>.KV.get(key, 'text')+ explicitJSON.parsein its own try) so transient blips don't reset counters.Low severity: counters are cosmetic and best-effort by design.
Flagged by the final whole-branch review of the scan-notifications feature (shipped in 615f972..e59b76c).