Skip to content

fix(ui): use GET-first flow for imported rooms to avoid invalid PUT#189

Merged
sanity merged 4 commits intomainfrom
fix-188
Mar 22, 2026
Merged

fix(ui): use GET-first flow for imported rooms to avoid invalid PUT#189
sanity merged 4 commits intomainfrom
fix-188

Conversation

@sanity
Copy link
Copy Markdown
Contributor

@sanity sanity commented Mar 22, 2026

Problem

When a user imports an identity (export → leave room → import), the room is created with a ChatRoomStateV1::default() that has an unsigned configuration. The sync process tries to PUT this invalid state to the contract, which fails with "State verification failed: Invalid signature: signature error" because only the room owner can sign the configuration. Since the PUT fails, the subscription is never established, and the user is stuck in an infinite loop of failed PUT retries with the same invalid default state. All subsequent message UPDATEs also fail.

Diagnostic report UF32XU confirms this: the first error is a PUT failure at 11:53:16, followed by repeated UPDATE failures, all with the same "Invalid signature" error on configuration validation.

Approach

For rooms awaiting subscription, detect "fresh imports" using the existing is_awaiting_initial_sync() method (empty members + empty messages + user is not owner). For these rooms:

  1. Send GET instead of PUT to retrieve the real state from the network
  2. On GET response, merge the retrieved state into the local room
  3. Then PUT the valid state with subscribe: true to register the contract code and establish the subscription
  4. Trigger signing key migration after the state is populated

This mirrors the existing invitation flow (which also does GET-first) but for the import path.

Testing

  • cargo test -p river-core — all pass
  • cargo test -p chat-delegate — all pass
  • cargo check for UI compiles cleanly (only pre-existing CSS asset warning)
  • No WASM changes — only ui/ code modified, no delegate migration needed

Changes

File Change
room_synchronizer.rs Split rooms-to-subscribe into GET-first (imports) vs PUT (normal)
get_response.rs Handle GET for imported rooms: PUT+subscribe with retrieved state
sync_info.rs Add get_sync_status() accessor

Closes #188

[AI-assisted - Claude]

sanity and others added 4 commits March 22, 2026 11:46
When importing an identity, the room is created with a default
ChatRoomStateV1 that has an unsigned configuration. The sync process
then tries to PUT this invalid state to the contract, which fails
because the configuration signature doesn't verify (only the room
owner can sign it). Since the PUT fails, the subscription is never
established, leaving the user stuck with default state. All subsequent
message UPDATEs also fail with "Invalid signature: signature error".

Fix: detect imported rooms (empty state, non-owner) and send a GET
request first to retrieve the real state from the network. When the
GET response arrives, PUT the valid state with subscribe=true to
register the contract code and establish the subscription.

Closes #188

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace pre-computed Vec of rooms needing GET-first with inline check
  per iteration, eliminating a separate collection pass and O(n) lookup
- Flatten needs_put_subscribe detection from a block with intermediate
  variables to a chained expression
- Standardize error log prefix to "Failed to send" for consistency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GlobalSignal writes must be deferred to avoid RefCell re-entrancy
panics per Dioxus WASM signal safety rules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move mark_initial_sync_complete and signing key migration inside
  PUT success path so they don't fire on PUT failure
- Use SYNC_INFO.with_mut() instead of .write() in error defer
- Reset to Disconnected on PUT failure for automatic retry
  (after GET+merge the state is valid, so retry takes normal PUT path)
- Add mark_needs_sync after successful PUT to persist state to delegate
- Add comment explaining why PUT uses retrieved_state (not merged state)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sanity sanity merged commit 2f10870 into main Mar 22, 2026
5 checks passed
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.

Import of ID continues to not work in simple test scenario.

1 participant