Glasses won't connect
Fix common first-connection failures on Meta Ray-Ban — no pairing dialog, session won't start, the DAT auth callback never fires, or an immediate disconnect.
Your app calls glasses.connection.connect() (or the user taps connect on ExtentosConnectionPage) and nothing usable happens — no pairing prompt, a session that never reaches Active, an auth callback that never returns, or a connection that drops the instant it opens. Connection failures surface as a typed ConnectError from the connect() / reconnect() result, or as a Disconnected state carrying a DisconnectCause — pattern-match those rather than guessing. This page maps each symptom to its cause and fix.
Kotlin leads the examples and is the source of truth; iOS exposes the same
ConnectError/GlassesStatetypes.
Quick checklist (verify these first)
- Glasses are powered, charged, and in range. A dead or out-of-range device surfaces as
ConnectError.NoDeviceAvailable. Confirm the glasses are paired in the Meta AI app first — Extentos connects to an already-bonded device, it doesn't replace Meta's own pairing. - Bluetooth permissions are granted at runtime. Missing
BLUETOOTH_CONNECT/BLUETOOTH_SCANsurfaces asConnectError.PermissionDenied. The SDK requestsBLUETOOTH_CONNECTat runtime, but your app must not have permanently denied it. - A foreground Activity is reachable. Meta registration (the pairing handoff) needs a live Activity — confirm your
activityProviderclosure returns the current top Activity, notnull. See Android lifecycle § Activity wiring. - The Meta DAT auth callback URL scheme is declared. The DAT auth round-trip returns through a custom URL scheme, not a universal/app link. If it's missing or misspelled, the callback never fires and connection hangs (see below).
- Run
validateIntegration. It catches the structural causes — missing Bluetooth permissions, an unwired bootstrap, an absent DAT configuration — before you ever hit the runtime failure. - Read the event log.
getEventLog(filter: 'lifecycle')shows the connection state walk (Registered→DeviceDiscovered→Connecting→Active) so you can see exactly where it stalls;getEventLog(filter: 'errors')surfaces the typed failure.
Pairing dialog never appears
The Meta registration / pairing UI is launched against a foreground Activity. If connect() resolves immediately to ConnectError.RegistrationRequired or nothing visibly happens:
- Your
activityProvider: () -> Activity?returnednull— the SDK had no Activity to launch registration from. Wire it to anActivityLifecycleCallbacks-tracked reference to the current top Activity. See Android lifecycle. - The install hasn't registered yet. There is no registration API for you to call — the SDK drives Meta's registration handoff itself, from inside
connect()(and therefore insideassistant.start(...)), using youractivityProviderto present the companion-app consent screen. SoRegistrationRequiredalmost always means the handoff couldn't run rather than that you forgot to start it: check thatactivityProviderreturns a live Activity, that the glasses are awake and connected in the Meta AI app, and that your package name + signing SHA-256 are registered with Meta. The packagedExtentosConnectionPagesupplies the Activity for you; an app without one supplies it throughactivityProvider. - You aren't enrolled in your own release channel. Meta only lets an account register your integration if it's a member of a channel you've assigned a version to — and that includes the account on your own test glasses. Correct App ID, correct signing SHA, and a still-failing registration usually means this. Check it before chasing
activityProvider. Needs firmware v125+; see release channels. - You're on the browser simulator, where there is no Bluetooth pairing at all — the surrogate runs in a browser tab. A missing pairing dialog in sim is expected; you attach via the session URL or auto-bind, not a pairing prompt.
Pairing succeeds but the session won't start
The connection state reaches Connecting (or DeviceDiscovered) and stalls, never flipping to Active:
ConnectError.PairingFailed— the handshake with the device failed. Power-cycle the glasses, confirm they're bonded in the Meta AI app, and retry. This is usually a transient DAT handshake failure.TransportError.HardwareUnavailable(carried insideDisconnectCause.TransportFailure) — the transport could not reach the hardware. On real glasses this is a Bluetooth/DAT-layer problem; in the simulator it means the browser surrogate denied webcam/mic permission or closed its tab.- A
SchemaMismatchtransport error means the SDK and backend protocol versions diverged — update to a matching SDK build.
Sim ≠ hardware here. A session that starts cleanly in the browser simulator does not guarantee real-hardware pairing succeeds — the simulator swaps the transport for a WebSocket and never exercises Bluetooth bonding or the DAT handshake. Treat real-hardware connection as its own verification pass.
DAT auth callback never fires
Meta DAT completes its auth/registration round-trip by redirecting back into your app through a custom URL scheme (DAT expects a custom scheme, not a universal link). When it's misconfigured, the system browser/Meta app opens, the user authorizes, and control never returns — the connection sits forever in Registered/Connecting.
- iOS: confirm
CFBundleURLTypesdeclares your custom scheme andLSApplicationQueriesSchemesincludesfb-viewapp, alongside theMWDATdict.generateConnectionModule(platform: "ios")emits the full set — re-run it if you hand-edited Info.plist and the callback stopped working. - Android: confirm the callback intent-filter scheme matches what you configured at DAT setup time, and that no other app claims the same scheme.
- The scheme registered in Meta Developer Center must match the one in your app exactly — a mismatch silently drops the callback.
Glasses connect but disconnect immediately
The state reaches Active and then drops straight back to Disconnected. Branch on the DisconnectCause:
DeviceDroppedConnection— Bluetooth fell over right after connecting (interference, the glasses going back to sleep, range). Retryable; reconnect with backoff. See handle disconnects.- A fold or overheat — surfaces today as
DeviceDroppedConnection(above); the dedicatedThermalCritical/HingesCloseddisconnect causes are declared but not yet produced. Wait for the condition to clear, then reconnect. TransportFailure— inspect the carriedTransportError(WebsocketClosed,Timeout,HardwareUnavailable) for specifics.
If a connection drops mid-operation, the in-flight call also returns its own typed error (e.g. CaptureError.NotConnected) — handle both the state observer and the per-call result, as covered in handle disconnects.
Related
- Error reference — every
ConnectError,CaptureError,AudioError, andTransportErrorpayload. - Sessions — the connection-state machine and what reaching
Activerequires. - Android manifest setup — the Bluetooth permissions and DAT entries the connection needs.
- Handle disconnects — recovering once a connection drops.
- Troubleshooting — other symptom-shaped fixes.
Related
Error reference
Every typed error the Extentos SDK can return — ConnectError, CaptureError, AudioError, TransportError, the ExtentosError umbrella, and the Meta-DAT DeviceSessionError — with their payload fields and meaning. Lifecycle operations return ExtentosResult<T, E> with these concrete failure variants rather than throwing; pattern-match them. Generated from the Rust core.
Sessions
How an Extentos session works — the glasses connection-state machine, what persists across backgrounding and reconnects, and the three browser-simulator roles.
Troubleshooting
Symptom-shaped fixes. Find your symptom, get the cause and the fix, with cross-links to error reference.