Skip to content

fix(private-rooms): replace alarming "secret v0 not available" placeholder during invite-acceptance sync window #284

@sanity

Description

@sanity

Symptom

User accepts invitation to a private room. For ~5-30 seconds afterwards, every message in the room renders as `[Encrypted message - secret v0 not available (have: [])]`. Then the back-fill arrives and messages decrypt.

The placeholder text is alarming — it suggests the room is permanently broken. It's actually a transient sync state.

Root cause

When the invitee accepts:

  1. GET response for the new room contract arrives. State contains messages + member list. No `encrypted_secrets` blob for the invitee's `member_id` yet — the owner's chat-delegate hasn't issued one yet.
  2. Invitee's `repopulate_secrets_from_state` runs, decrypts 0 secrets. Local `secrets` HashMap empty.
  3. Renderer falls back to the "secret vN not available (have: [])" placeholder.
  4. Invitee PUTs join_event. Owner's delegate sees the new member via `ContractNotification`, runs back-fill, publishes blob.
  5. Update notification reaches the invitee → `repopulate_secrets_from_state` runs again → blob decrypted → messages decrypt.

The window between (3) and (5) is what users see. It's a real network round-trip — order of seconds in practice.

Fix shape

In the renderer (`ui/src/components/conversation.rs`, message bubble rendering), when:

  • room is private AND
  • local `room_data.secrets` is empty AND
  • the message is private-encrypted

show a friendly placeholder instead:

  • First ~30 seconds: "Decrypting your invitation — this should only take a moment" with a spinner.
  • After 30 seconds with still no secrets: "Still waiting for the room owner to share keys. Try refreshing if this persists."

Optionally also hide the message list entirely behind a centred "Syncing your invitation…" placeholder until first decryption succeeds. Less jarring when decryption flips on.

Logs (user reproduction, build 94fcd8c)

```
get_response.rs:237 GET response: decrypted 0 room secret(s) for member MemberId(QC2UMYUC)
get_response.rs:257 Private room but no secret available for encrypting nickname, using public
```

Then several seconds of state updates pass. Eventually the user sends a message at `secret_version: 2` — confirming the back-fill landed by then.

Related

[AI-assisted - Claude]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions