Skip to content

fix(alerts): prevent duplicate create retries - #588

Open
Kewe63 wants to merge 2 commits into
nansen-ai:mainfrom
Kewe63:fix/587-alert-mutation-retry-cache
Open

fix(alerts): prevent duplicate create retries#588
Kewe63 wants to merge 2 commits into
nansen-ai:mainfrom
Kewe63:fix/587-alert-mutation-retry-cache

Conversation

@Kewe63

@Kewe63 Kewe63 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #587.

Smart Alert mutations inherited the generic response cache, and the non-idempotent create path also inherited generic transport/status retries. A lost response could therefore submit the same create up to four times, while a repeated identical mutation could be satisfied from cache without reaching the API.

Changes

  • disable both retry and response caching for alertsCreate()
  • disable response caching for alertsUpdate(), alertsToggle(), and alertsDelete()
  • retain existing retry behavior for update/toggle/delete, whose requests set explicit state or delete a specific resource
  • add a focused regression proving an ambiguous create failure produces one fetch attempt
  • add parameterized cache regressions for all four mutation methods
  • use fake timers so the pre-fix retry regression remains deterministic without waiting for backoff delays
  • add a patch changeset

Read-only Smart Alert methods are unchanged.

Regression proof

With the new tests applied to current main before the fix:

Test Files  2 failed (2)
Tests       5 failed | 210 skipped (215)

The failures showed:

  • alertsCreate() made 4 fetch attempts instead of 1 after an ambiguous network failure
  • each mutation method made only 1 fetch across 2 identical calls because the second response came from cache

With this fix:

Test Files  2 passed (2)
Tests       5 passed | 210 skipped (215)

Full suite:

Test Files  67 passed (67)
Tests       2683 passed | 16 skipped (2699)
Duration    181.21s

Additional checks:

  • npm run lint — passed
  • git diff --check — passed
  • npm pack --ignore-scripts --dry-run — passed; 85 package files, no test artifacts included
  • npm audit --omit=dev --json — 0 production vulnerabilities

All regression tests used a temporary HOME, fake credentials, mocked fetch responses, and no external network access.

Compatibility and risk

  • no public API, CLI, schema, or response-format changes
  • a failed create now returns after the first ambiguous failure instead of retrying
  • identical mutation calls always reach the API rather than reusing a local cached response
  • read-only alert caching and generic retry behavior elsewhere are unchanged
  • this does not assume or claim server-side create idempotency; disabling client replay is the safe behavior while no idempotency contract is available

Checklist

  • Tests pass (npm test)
  • src/schema.json updated if new commands or flags were added — no command or flag changes
  • README.md updated if new top-level commands or categories were added — no command changes
  • Changeset added (.changeset/avoid-duplicate-alert-create.md)

Disable generic retry for non-idempotent alert creation and bypass the response cache for all Smart Alert mutations. Add focused retry and cache regressions.\n\nFixes nansen-ai#587
@nansen-pr-reviewer

nansen-pr-reviewer Bot commented Sep 4, 2026

Copy link
Copy Markdown

pr-reviewer Summary for #bd50a04

No issues found

The code review completed successfully with no findings.

Review effort: 2/5 (Simple)

Summary

This PR is a clean, targeted fix. The production change (src/api.js) is exactly three lines — adding { cache: false, retry: false } to alertsCreate() and { cache: false } to alertsUpdate(), alertsToggle(), and alertsDelete() — using an option-pass-through pattern (options.cache !== false, options.retry !== false) that is already established throughout the request() method and used in other callers like getAccount(). The regression tests are well-structured, use fake timers correctly (matching the pattern in the surrounding test file), restore real timers via the existing afterEach safety net, and isolate HOME to avoid polluting the real cache directory. The changeset is present, correctly scoped as patch, and the semver bump is appropriate for a bug fix. No issues found.


Token usage: 6,872 input, 3,009 output, 290,093 cache read, 34,814 cache write | Usage Guide

New pushes are reviewed automatically with a 10-minute cooldown between reviews. To request a review at any time, comment @nansen-pr-reviewer re-review.

nansen-pr-reviewer[bot]
nansen-pr-reviewer Bot previously approved these changes Sep 4, 2026

@nansen-pr-reviewer nansen-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved

This PR was automatically approved because:

  • Claude recommends approval
  • Claude assessed this as a moderate effort change
  • The effort level is within the auto-approval threshold of 2
  • No high or critical issues were detected

If you have any concerns, please request a manual review.

Follow the existing api.test.js live-test convention so the regression does not access the absent mockFetch fixture when NANSEN_LIVE_TEST=1.

@nansen-pr-reviewer nansen-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved

This PR was automatically approved because:

  • Claude recommends approval
  • Claude assessed this as a moderate effort change
  • The effort level is within the auto-approval threshold of 2
  • No high or critical issues were detected

If you have any concerns, please request a manual review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Smart Alert mutations inherit unsafe retry and response-cache behavior

1 participant