Skip to content

fix(wallet-cli): retry sendCommand only on ECONNREFUSED - #9608

Merged
sirtimid merged 3 commits into
mainfrom
sirtimid/wallet-cli-idempotency-safe-retry
Jul 22, 2026
Merged

sirtimid merged 3 commits into
mainfrom
sirtimid/wallet-cli-idempotency-safe-retry

Conversation

@sirtimid

@sirtimid sirtimid commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

Explanation

wallet-cli's daemon client sendCommand retried a failed request once on both ECONNREFUSED and ECONNRESET. Only ECONNREFUSED is safe to retry — it means the connection was never established, so the daemon never received the request. ECONNRESET can drop after the daemon received and acted on the request, so a blind resend could execute a non-idempotent action (e.g. broadcast a transaction) twice.

This restricts the retry to ECONNREFUSED; ECONNRESET now surfaces to the caller (where makeDaemonConnectionError already renders a distinct "lost the connection to the daemon" message). Updates the sendCommand and PingUnreachableReason JSDoc accordingly.

Latent today (all current callers are idempotent), but a prerequisite for shipping any send/sign/transfer command.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Changes daemon RPC failure semantics in a wallet CLI path that will back send/sign flows; the tradeoff is correct for safety but callers may see more surfaced connection errors instead of silent retries.

Overview
Narrows daemon JSON-RPC client retry behavior so sendCommand retries once only on ECONNREFUSED, not on ECONNRESET. A reset can happen after the daemon already handled the request, so a blind resend could run a non-idempotent action (e.g. broadcast) twice; those errors now propagate to callers instead.

pingDaemon still classifies ECONNRESET as unreachable with reason refused, but inherits the no-retry rule via sendCommand. JSDoc, changelog, and tests were updated to match.

Reviewed by Cursor Bugbot for commit 1fa26b8. Bugbot is set up for automated code reviews on this repo. Configure here.

sirtimid and others added 3 commits July 22, 2026 18:57
The daemon client's `sendCommand` retried a request once on both
ECONNREFUSED and ECONNRESET. ECONNRESET can drop after the daemon has
already received and acted on the request, so blindly re-sending a
non-idempotent request (e.g. a transaction broadcast) could execute it
twice. Restrict the retry to ECONNREFUSED — where the connection was
never established, so the daemon provably never received the request —
and surface ECONNRESET to the caller instead.

This hardens the retry path before any mutating send/sign/transfer RPC
becomes reachable over the daemon socket.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sirtimid
sirtimid marked this pull request as ready for review July 22, 2026 16:19
@sirtimid
sirtimid requested review from a team as code owners July 22, 2026 16:19
@sirtimid
sirtimid temporarily deployed to default-branch July 22, 2026 16:19 — with GitHub Actions Inactive
@sirtimid
sirtimid enabled auto-merge July 22, 2026 16:20
@sirtimid
sirtimid added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit d6c4e60 Jul 22, 2026
431 checks passed
@sirtimid
sirtimid deleted the sirtimid/wallet-cli-idempotency-safe-retry branch July 22, 2026 16:48

This branch was previously deployed

1 inactive deployment
default-branch — 1fa26b86 Deployed Jul 22, 2026 by sirtimid via Determine whether this PR is a release PR #2452
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.

wallet-cli: make sendCommand retry idempotency-safe before mutating RPC ships

2 participants