Reference
Errors and troubleshooting
Recover from iframe, authentication, credential, and embedding failures.
Iframe does not load
Check the app document's HTTP response headers. frame-ancestors must allow both Zetapad production origins. Remove conflicting X-Frame-Options: DENY and SAMEORIGIN headers. A CSP meta tag cannot configure frame-ancestors.
Check the final URL after redirects. Its origin must match the registered launch origin. Local HTTP previews may need an HTTPS tunnel inside an HTTPS parent. See embedding.
Room waits for readiness
Install the listener before calling ready. Send the version 2 request envelope, empty params, and a unique request ID. Check the exact target origin, reply origin, and event.source === window.parent.
Zetapad shows retry controls after 15 seconds without readiness. The browser example's individual request timeout is two minutes to allow time for consent; that example timeout is not the room's readiness timer.
Protocol errors
| Code | Recovery |
|---|---|
CONSENT_DENIED | Member cancelled; stop initialization. Zetapad closes the room. |
AUTHENTICATION_REQUIRED | The bridge could not issue an approved code; stop initialization and obtain consent again. |
ACCESS_REVOKED | Reopen after a registration update, then authenticate and obtain new consent if requested. |
STALE_LAUNCH | Reopen the room and complete a new ready handshake. |
INVALID_TOKEN | Reopen the room if its launch expired; obtain fresh authentication if issued access expired. |
REQUEST_IN_PROGRESS | Wait for the pending authentication or consent request. |
DUPLICATE_REQUEST | Use a new request ID; do not replay the old request. |
APP_UNAVAILABLE | Check publication, deletion, and whether the current member may preview the app; reopen when available. |
API_ERROR | The bridge could not classify the failure; stop initialization and retry when services recover. |
INTERNAL_SERVER_ERROR | Temporary backend failure; stop the current operation and retry later. |
Malformed and untrusted requests receive no response. Inspect your envelope, allowed params, registered origin, and source window if a request times out.
Where to read member identity
Version 2 authenticate returns only code, expiresIn, and state. Your backend must exchange the code with its client ID and secret, then call userinfo to retrieve the verified userId and approved fields. This applies even with scopes: []. Complete the authentication flow before starting the app.
REST errors
INVALID_CLIENT requires checking the backend's client ID and current secret. Do not retry with a secret that was rotated or deleted.
INVALID_TOKEN requires a fresh code or token. Authorization codes expire after 60 seconds and are consumed once. Access tokens expire after 15 minutes. There is no refresh-token endpoint.
ACCESS_REVOKED and APP_UNAVAILABLE require ending protected app access until the member can reopen and authenticate. Registration saves, unpublishing, deletion, rotation, and disconnection invalidate issued access immediately. A scope or launch-origin change also requires fresh member consent; follow scope changes and reauthentication.
BAD_USER_INPUT requires fixing the token request JSON. INTERNAL_SERVER_ERROR is a temporary service failure. Handle errors by their stable codes, not message text.
App login fails in an iframe
Confirm that the state challenge and login request use the same server-side visitor session. A mismatched, expired, or consumed state must reject login. The browser must never supply its own server-session identity.
Check your app's embedded session mechanism. Secure cross-site cookies generally require SameSite=None, but browsers may restrict them. Zetapad's own authentication does not depend on third-party cookies; your app's session configuration still matters.
Direct access still works
frame-ancestors alone does not block a top-level browser tab. Apply the document guard and browser startup check in restrict app access, including to nested routes.
If direct API requests work without login, add a current server-session and userinfo check to every protected handler. A valid ready result, query parameter, referrer, or browser-supplied profile cannot authorize backend access.