Skip to content

Collections: Maximum update depth exceeded with 300+ vouchers (Base Sepolia) #18

@riseandshaheen

Description

@riseandshaheen

Summary

On the My Collections page (/collections), loading 300+ vouchers triggers a client-side React error: Uncaught Error: Maximum update depth exceeded, which usually indicates repeated setState / hook updates in a tight loop. The page becomes unusable at this scale.

Environment

  • Network: Base Sepolia
  • Rollups node: Hosted on Fly.io (Cartesi Rollups HTTP endpoint used by jam-ui)
  • App: jam-ui (Comet)
  • Page: Collections — apps/jam-ui/src/app/collections/page.tsxVouchersView

Steps to reproduce

  1. Use an account that has many vouchers (e.g. 300+) on Base Sepolia.
  2. Connect the wallet in the UI (pointing at the Fly.io-hosted rollups endpoint as configured).
  3. Open My Collections (/collections).
  4. Observe the browser console and page behavior.

Expected behavior

  • The collections list loads (possibly with loading state).
  • UI remains stable; user can scroll and interact (execute vouchers, etc.), or sees a clear limit/pagination message if the product caps batch size.

Actual behavior

  • Error: Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
  • Collections view does not behave correctly at this voucher count.

Technical notes (for maintainers)

Relevant code paths:

  • apps/jam-ui/src/components/vouchers/VouchersView.tsx
    • VoucherList uses useMemo(..., userVouchers) without wrapping in a single-element dependency array ([userVouchers]). The second argument to useMemo is a dependency list; passing the vouchers array directly can be interpreted as one dependency per array element, which is fragile at 300+ items.
    • Each row renders ExecuteButton, which mounts multiple wagmi hooks per voucher (useReadCartesiApplicationWasOutputExecuted, useSimulateCartesiApplicationExecuteOutput, etc.).
    • MintVoucher calls useFindJam per mint voucher, multiplying concurrent queries when many mint vouchers exist.
  • apps/jam-ui/src/components/vouchers/queries.tsx
    • useGetUserVouchers uses useOutputs with OUTPUTS_LIMIT = 200 and offset: 0 — at 300+ vouchers, outputs may be incomplete or the UI still attempts to render a very large list; consider pagination / higher limits / alignment with RPC.

Hypothesis (non-exclusive): Scale of simultaneous hooks + query subscriptions + possible useMemo dependency misuse may drive excessive re-renders or update cascades.

Suggested directions (not prescriptive)

  • Fix useMemo dependencies in VoucherList (e.g. [userVouchers]).
  • Virtualize or paginate the collections list so DOM and hook count stay bounded.
  • Throttle / batch per-voucher chain reads and execution prep (or lazy-load Execute when in view).
  • Revisit useFindJam usage for mint rows (batch or cache jam metadata).
  • Align useOutputs limit / offset with real max collection size and document limits in the UI.

Acceptance criteria (proposal)

  • /collections loads without React "maximum update depth" errors with ≥ 300 vouchers (or product-defined max).
  • Clear UX if a hard cap exists (pagination, "load more," message).

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions