Undecryptable message: show the specific reason and the one action that fixes it #159

Closed
opened 2026-09-17 23:06:34 -04:00 by jared · 1 comment
Owner

Verify what the placeholder says today for an undecryptable event (DecryptionError codes from matrix-js-sdk rust-crypto: HISTORICAL_MESSAGE_NO_KEY_BACKUP, HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED, HISTORICAL_MESSAGE_WORKING_BACKUP ("key backup is working, but we still do not (yet) have the key"), MEGOLM_KEY_WITHHELD(_FOR_UNVERIFIED_DEVICE), UNKNOWN_SENDER_DEVICE, UNSIGNED_SENDER_DEVICE, MEGOLM_UNKNOWN_INBOUND_SESSION_ID).

Scope

  • Map each code to one sentence + one action button, rendered inside the existing placeholder (no modal): backup unconfigured → Set up key backup; backup working but key not yet there → "Waiting for key backup… " with Retry; key withheld for unverified device → Verify this session; unknown inbound session → Request key from my other devices (crypto.requestRoomKey / re-request); sender-side problems → plain text, no button.
  • Never expose raw codes to users (keep them in the tooltip for support / Crypto Diagnostics).
  • Unit-test the code→copy/action mapping (utils/decryptionReason.ts).
Verify what the placeholder says today for an undecryptable event (`DecryptionError` codes from matrix-js-sdk rust-crypto: `HISTORICAL_MESSAGE_NO_KEY_BACKUP`, `HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED`, `HISTORICAL_MESSAGE_WORKING_BACKUP` ("key backup is working, but we still do not (yet) have the key"), `MEGOLM_KEY_WITHHELD(_FOR_UNVERIFIED_DEVICE)`, `UNKNOWN_SENDER_DEVICE`, `UNSIGNED_SENDER_DEVICE`, `MEGOLM_UNKNOWN_INBOUND_SESSION_ID`). ### Scope - Map each code to one sentence + one action button, rendered inside the existing placeholder (no modal): backup unconfigured → *Set up key backup*; backup working but key not yet there → "Waiting for key backup… " with *Retry*; key withheld for unverified device → *Verify this session*; unknown inbound session → *Request key from my other devices* (`crypto.requestRoomKey` / re-request); sender-side problems → plain text, no button. - Never expose raw codes to users (keep them in the tooltip for support / Crypto Diagnostics). - Unit-test the code→copy/action mapping (`utils/decryptionReason.ts`).
jared added this to the Features 2026-Q4 milestone 2026-09-17 23:06:34 -04:00
jared added the enhancementpriority: mediumsecurityuxarea: messaging labels 2026-09-17 23:06:34 -04:00
jared self-assigned this 2026-09-17 23:06:34 -04:00
Author
Owner

Verified first: the placeholder was the bare "Unable to decrypt message" for every code. Done in 0e267189:

utils/decryptionReason.ts maps every DecryptionFailureCode to one sentence + at most one action (unit test iterates the whole enum and asserts no raw code or code-like text in the copy):

  • HISTORICAL_MESSAGE_NO_KEY_BACKUP → "…no key backup exists — set one up so your next session can read history." → Set up key backup
  • HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED → "Your key backup exists but this session can't open it yet." → Unlock key backup
  • HISTORICAL_MESSAGE_WORKING_BACKUP → "Waiting for the key from your backup…" → Retry
  • MEGOLM_KEY_WITHHELD_FOR_UNVERIFIED_DEVICEVerify this session
  • MEGOLM_UNKNOWN_INBOUND_SESSION_ID / OLM_UNKNOWN_MESSAGE_INDEX → "…it is being requested from your other devices." → Retry (rust-crypto has no public re-request API — it re-requests by itself; Retry re-runs decryptEventIfNeeded)
  • USER_NOT_JOINED, KEY_WITHHELD, SENDER_IDENTITY_PREVIOUSLY_VERIFIED, UNSIGNED_SENDER_DEVICE, UNKNOWN_SENDER_DEVICE → plain text, no button.

The backup/verify buttons open Settings → Devices through a new settingsRequestAtom (any component can now open settings at a page). The raw code lives in the placeholder's tooltip.
placeholder

Verified first: the placeholder was the bare "Unable to decrypt message" for every code. Done in `0e267189`: `utils/decryptionReason.ts` maps every `DecryptionFailureCode` to one sentence + at most one action (unit test iterates the whole enum and asserts no raw code or code-like text in the copy): - `HISTORICAL_MESSAGE_NO_KEY_BACKUP` → "…no key backup exists — set one up so your next session can read history." → **Set up key backup** - `HISTORICAL_MESSAGE_BACKUP_UNCONFIGURED` → "Your key backup exists but this session can't open it yet." → **Unlock key backup** - `HISTORICAL_MESSAGE_WORKING_BACKUP` → "Waiting for the key from your backup…" → **Retry** - `MEGOLM_KEY_WITHHELD_FOR_UNVERIFIED_DEVICE` → **Verify this session** - `MEGOLM_UNKNOWN_INBOUND_SESSION_ID` / `OLM_UNKNOWN_MESSAGE_INDEX` → "…it is being requested from your other devices." → **Retry** (rust-crypto has no public re-request API — it re-requests by itself; Retry re-runs `decryptEventIfNeeded`) - `USER_NOT_JOINED`, `KEY_WITHHELD`, `SENDER_IDENTITY_PREVIOUSLY_VERIFIED`, `UNSIGNED_SENDER_DEVICE`, `UNKNOWN_SENDER_DEVICE` → plain text, no button. The backup/verify buttons open Settings → Devices through a new `settingsRequestAtom` (any component can now open settings at a page). The raw code lives in the placeholder's tooltip. ![placeholder](https://code.lotusguild.org/attachments/021a5641-712a-4992-a269-2414975d3605)
jared closed this issue 2026-09-19 13:24:57 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#159