Skip to content

fix(cli): activate contract migration in riverctl room operations#193

Merged
sanity merged 4 commits intomainfrom
fix-192
Mar 24, 2026
Merged

fix(cli): activate contract migration in riverctl room operations#193
sanity merged 4 commits intomainfrom
fix-192

Conversation

@sanity
Copy link
Copy Markdown
Contributor

@sanity sanity commented Mar 24, 2026

Problem

ensure_room_migrated() was fully implemented but never called from any room operation. When the bundled room contract WASM changed (e.g., after a release), riverctl would compute the new contract key and try to GET/UPDATE against it — but no state existed at that key yet, causing 30-second timeouts on every operation (message send, member list, etc.).

Additionally, the migration-needed check was a no-op: load_rooms() already regenerates contract_key to match the current WASM before ensure_room_migrated() reads it, so the stored_key == expected_key comparison was always true.

Approach

  1. Wire ensure_room_migrated() into get_room() and subscribe_and_stream() — these are the two entry points that all room operations flow through. Migration runs transparently before the first GET.

  2. Fix the migration-needed check — instead of comparing the (already-regenerated) stored key against expected, check whether previous_contract_key is set. load_rooms() sets this field when it detects a key mismatch, which is exactly the signal that migration is needed.

Testing

  • New unit test test_load_rooms_sets_previous_contract_key_on_mismatch validates that load_rooms() correctly detects WASM changes and populates previous_contract_key
  • All 8 existing riverctl tests continue to pass
  • cargo clippy and cargo fmt clean

Closes #192

[AI-assisted - Claude]

sanity and others added 4 commits March 24, 2026 14:46
The ensure_room_migrated() function was fully implemented but never
called. When bundled WASM changed (e.g., after a release), riverctl
would try to GET/UPDATE the new contract key which had no state yet,
causing timeouts.

Two bugs fixed:
1. Wire ensure_room_migrated() into get_room() and subscribe_and_stream()
   so migration runs automatically before any room operation.
2. Fix the migration-needed check: load_rooms() already regenerates the
   stored key to match current WASM, so comparing stored vs expected was
   always equal. Now checks previous_contract_key instead.

Closes #192

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace unwrap_or("unknown") with unwrap() since we already early-return
  when previous_contract_key_str is None
- Simplify test assertions using as_deref() pattern
- Remove unnecessary mut binding in test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
subscribe_and_stream called ensure_room_migrated then get_room which
also calls ensure_room_migrated. Removed the explicit call since
get_room handles migration internally. Also added assertion that
previous_contract_key is None for rooms with current WASM.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Clear previous_contract_key after ALL successful migration paths
   (timeout and catch-all), not just the "already exists" path.
   Prevents redundant migration re-attempts on subsequent calls.

2. Restore "Room not found" guard in subscribe_and_stream that was
   lost when refactoring to use get_room for migration.

3. Fix misleading test comment about load_rooms behavior during
   add_room (file doesn't exist yet, so no regeneration occurs).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sanity sanity merged commit f1cb454 into main Mar 24, 2026
6 checks passed
@sanity sanity deleted the fix-192 branch March 24, 2026 20:03
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.

feat(cli): riverctl should handle room contract migration automatically

1 participant