Skip to content

Spike: missing swapperName #11532

@gomesalexandre

Description

@gomesalexandre

Overview

Able to repro this one quite often locally, we should absolutely find the smoking gun
Gut feel is something is wrong state-wise, as clearing cache usually fixes this.

Claude spike below:

Able to repro this one quite often locally, we should absolutely find the smoking gun
Gut feel is something is wrong state-wise, as clearing cache usually fixes this.

Claude Spike

Error: Uncaught (in promise) Error: missing swapperName thrown at useTradeExecution.tsx:128

Root Cause: State desynchronization between activeQuoteMeta and tradeQuotes in Redux.

The Bug Flow

  1. User gets quote and selects it → activeQuoteMeta is set
  2. Something triggers clearTradeQuotes action (possibly quote refresh, input change, or component re-mount)
  3. tradeQuotes are cleared BUT activeQuoteMeta is intentionally preserved (tradeQuoteSlice.ts:29)
  4. User clicks "Sign and Broadcast"
  5. selectActiveSwapperName selector checks if quote exists: tradeQuotes[activeQuoteMeta.swapperName][activeQuoteMeta.identifier]
  6. Quote doesn't exist (was cleared) → selector returns undefined
  7. Execution fails: "missing swapperName"

Key Code Locations

Where activeQuoteMeta is preserved:
src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts:25-31

clearTradeQuotes: create.reducer(state => ({
  ...initialState,
  tradeExecution: state.tradeExecution,
  activeQuoteMeta: state.activeQuoteMeta,  // ← Preserved to handle "backing out from preview"
  sortOption: state.sortOption,
}))

Where swapperName check happens:
src/state/slices/tradeQuoteSlice/selectors.ts:214-227

selectActiveSwapperName: (activeQuoteMetaOrDefault, tradeQuotes) => {
  if (activeQuoteMetaOrDefault === undefined) return
  if (tradeQuotes[activeQuoteMetaOrDefault.swapperName]?.[activeQuoteMetaOrDefault.identifier]) {
    return activeQuoteMetaOrDefault.swapperName
  }
  // Returns undefined if quote doesn't exist
}

Investigation Needed

  1. When does clearTradeQuotes get called?

    • During quote refresh?
    • When user changes input amounts?
    • On component re-mount?
    • Add logging to track all clearTradeQuotes dispatches
  2. Is preserving activeQuoteMeta still necessary?

    • Comment mentions "backing out from preview"
    • Test: preview → back → preview navigation
    • Does it actually need the preserved quote, or can it re-select?
  3. Race condition timing:

    • Is there a timing window between selecting quote and executing?
    • Could quote refresh happen while user is on confirm screen?

Potential Fixes

Option A: Stop preserving activeQuoteMeta (simplest)

  • Remove activeQuoteMeta: state.activeQuoteMeta from clearTradeQuotes reducer
  • Risk: May break navigation UX (quotes need re-selection when backing out)

Option B: Conditional preservation

  • Add parameter to clearTradeQuotes to control when to preserve
  • Only preserve when needed for navigation
  • Clear when quote refresh happens

Option C: Validate quote exists before execution

  • In execution hook, check if quote still exists in tradeQuotes
  • If not, re-fetch or show error to user
  • More defensive but doesn't fix root cause

Recommended Approach

Investigate Option A first:

  1. Remove activeQuoteMeta preservation
  2. Test swap execution (should fix the error)
  3. Test navigation flow (preview → back → preview)
  4. If navigation breaks, implement Option B

References and additional details

N/A

Acceptance Criteria

  • That sneaky error is gone

Need By Date

No response

Screenshots/Mockups

No response

Estimated effort

No response

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions