Client Exception
Anything that can go wrong, as one case per kind an app can branch on: the same kinds as every other head (decision 0090). Swift sees an enum with a reason on each case; Kotlin a sealed exception class with one subclass per kind. A case may be added, so switch with a default.
Inheritors
Types
The service document could not be fetched or read.
The address is bound to a different device identity (trust on first use): resume from the saved state, or use another device number.
A protocol or cryptographic failure, or a bug: worth reporting.
The caller's own input was wrong: a malformed address or config, a message over the size limit.
The username is not one the server accepts.
The network or the transport failed; retry later.
The address is not registered.
The server asked for a slower pace: too many failed sign-ins, or the recipient's queue is full. Back off and retry.
The server could not process the request; nothing was applied.
The credentials were refused, or the session expired. Coarse by design.
A sign-up was refused for another reason: registration is closed or the handle is reserved.
The persisted state was refused: altered, older than the last send, or its secure-storage key is wrong. Whatever else a SecureStore implementation raises surfaces as this case, with its reason. Do not delete the blob.
The platform's secure store could not be reached: a Keychain before first unlock, a Keystore that needs the user. Nothing was refused; retry after unlock and keep the blob. A SecureStore implementation throws this case for exactly that, and the client passes it through.
The API key selects no tenant.
The username is already taken in this tenant.
The password is too weak.