Wrong API host
Wrong API host
Symptom: Token requests fail or return an unexpected error page.Cause: Sending API requests to
aveid.net instead of api.aveid.net.Fix:Token request rejected as invalid
Token request rejected as invalid
Symptom: Token endpoint returns
400 invalid_request even though you’re sending the right values.Cause: A required field is missing or misspelled. The error_description names the fields Ave couldn’t read. Ave accepts OAuth snake_case names and their camelCase equivalents, in a form-encoded or JSON body.Fix:PKCE verifier mismatch
PKCE verifier mismatch
Symptom: Token exchange returns
invalid_grant.Causes:- Base64url encoding bug in the verifier
- Stored verifier was overwritten before exchange (e.g. user opened a second tab)
- Multiple concurrent login flows racing
sessionStorage, and clear it immediately after a single use.Missing id_token in the response
Missing id_token in the response
Symptom: Token response has
access_token but no id_token.Cause: The openid scope was not requested or was not granted for your app.Fix: Add openid to your requested scopes:Refresh token suddenly returns invalid_grant
Refresh token suddenly returns invalid_grant
Symptom: A refresh request that previously worked now returns
invalid_grant.Possible causes:- Token expired (refresh tokens have a maximum lifetime)
- Token was revoked by the user or by the server
- Reuse detection triggered — you sent the same refresh token twice (rotation means the old one is immediately invalidated after first use)
invalid_grant on a refresh as a terminal session loss for that session and re-authenticate the user. Store the new refresh token returned by every successful refresh immediately. Ave only invalidates the rotated token lineage that was reused, so unrelated sessions on other devices should stay signed in.E2EE app key fails to decode
E2EE app key fails to decode
Symptom: Always normalize base64 strings from URL fragments before decoding.
atob() throws, or the decrypted key is garbage.Cause: The app key is delivered via URL fragment (#app_key=...). Browsers silently replace + with a space in fragment parameters, breaking base64 decoding.Fix:No encryption key after sign-in
No encryption key after sign-in
Symptom: Sign-in succeeds, but
app_key or app_private_key is missing.Possible causes:- The sign-in did not request
e2ee:symmetricore2ee:asymmetric - The code was exchanged without reading the fragment, for example on a server callback route
- The fragment was stripped by a router or redirect before the SDK read it
completeOAuthCallback, the embed’s onTokens, or mergeAppEncryptionFromUrl in client code before anything rewrites the URL.Existing data no longer decrypts
Existing data no longer decrypts
Symptom: Ciphertext written earlier fails to decrypt with the key from a new sign-in.Possible causes:
- The user signed in with a different identity, which has different keys
- A sign-in requested
e2ee:reset, which rotated the keys - The user disconnected your app in Ave, which deleted its keys, and then signed in again
*_old keys delivered with the new ones to re-encrypt. If a trusted session still holds the original key, see Recover an app key. Never overwrite ciphertext you could not decrypt.User profile data is stale
User profile data is stale
Symptom: Display name, avatar, or email shown in your app is outdated.Cause: Profile data cached from the initial token exchange is never refreshed.Fix: Re-fetch the profile from
/api/oauth/userinfo on each login, or when you need fresh data.Data showing up under the wrong user
Data showing up under the wrong user
Symptom: One user can see another user’s data, or data is missing after a user changes identity.Cause: App is storing data keyed by
handle (username) instead of identityId. Handles can change; identityId is stable.Fix: Always key user data by the sub claim from the JWT (which is the identityId). Never rely on handle as a stable identifier.