Fix RefCell borrow panic during async gateway operations #7

Closed
opened 2026-02-27 14:07:32 +00:00 by mik-tf · 0 comments
Member

Problem

When navigating the app while logged in, a RefCell already mutably borrowed panic occurs at crates/frontend/src/main.rs:356:25. This happens because render-time code calls borrow() on the Rc<RefCell<HeroLedgerClient>> while an async gateway operation holds borrow_mut() via take_gw().

Root Cause

Dioxus re-renders components while futures are suspended at .await points. The account_id_string() method on HandleExt calls self.borrow() during render, conflicting with take_gw() which calls borrow_mut() during async I/O.

Affected components:

  • ActIdentity (main.rs)
  • PreparePreRegister (prepare_pre_register.rs)
  • NodeLookup (nodes.rs)

Solution

Introduce a Signal<GatewayAccountId> that is set once when gateway credentials are established. All render-time code reads from this signal instead of borrowing the RefCell. The RefCell is then only ever accessed by async code via the existing take_gw/put_gw pattern.

Also clean up compiler warnings (unused import in async_yield, dead code on vault_list_with_keys).

## Problem When navigating the app while logged in, a `RefCell already mutably borrowed` panic occurs at `crates/frontend/src/main.rs:356:25`. This happens because render-time code calls `borrow()` on the `Rc<RefCell<HeroLedgerClient>>` while an async gateway operation holds `borrow_mut()` via `take_gw()`. ## Root Cause Dioxus re-renders components while futures are suspended at `.await` points. The `account_id_string()` method on `HandleExt` calls `self.borrow()` during render, conflicting with `take_gw()` which calls `borrow_mut()` during async I/O. Affected components: - `ActIdentity` (main.rs) - `PreparePreRegister` (prepare_pre_register.rs) - `NodeLookup` (nodes.rs) ## Solution Introduce a `Signal<GatewayAccountId>` that is set once when gateway credentials are established. All render-time code reads from this signal instead of borrowing the RefCell. The RefCell is then only ever accessed by async code via the existing `take_gw`/`put_gw` pattern. Also clean up compiler warnings (unused import in `async_yield`, dead code on `vault_list_with_keys`).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mycelium/www_migrate_mycelium#7
No description provided.