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.
Generated from source. The error enums below are emitted from the Rust core (
core/extentos-core/src/types/errors.rs), which is codegen'd into the Kotlin and Swift SDKs. The same variants exist on both platforms; Kotlin uses the PascalCase names shown, Swift the lowerCamelCase equivalents (TransportFailure→.transportFailure).
How errors surface
Lifecycle operations don't throw — they return an ExtentosResult<S, F> with a typed failure variant. This is DAT's own convention and avoids coroutine-cancellation footguns. Pattern-match the result; don't wrap it in runCatching (which only catches thrown exceptions and would mask the typed error):
when (val r = glasses.camera.capturePhoto()) {
is ExtentosResult.Ok -> render(r.value) // Photo
is ExtentosResult.Err -> when (val e = r.error) { // CaptureError
is CaptureError.PermissionDenied -> requestCameraPermission()
is CaptureError.ThermalCritical -> toast("Glasses too hot — let them cool")
is CaptureError.DisabledByUser -> explainToggle(e.toggle)
else -> log(e)
}
}Helpers on the Kotlin ExtentosResult: .map { }, .flatMap { }, .valueOrNull(), .errorOrNull().
The Swift shape differs in names, not model — ExtentosResult is .success(Success) / .failure(Failure), with map / flatMap and optional success / failure properties instead of valueOrNull() / errorOrNull():
switch await glasses.camera.capturePhoto() {
case .success(let photo): render(photo)
case .failure(let error): // CaptureError
switch error {
case .permissionDenied: requestCameraPermission()
case .thermalCritical: toast("Glasses too hot — let them cool")
default: log(error)
}
}The code + message carried by the PlatformError / TransportFailure variants is the shell's stable machine tag for a native-origin failure (the original native exception is logged to the event log at the catch site, not carried across the FFI).
Connection errors
ConnectError
Returned by glasses.connection.connect().
| Variant | Payload | Meaning |
|---|---|---|
NoDeviceAvailable | — | No paired or otherwise known device is available to connect to. |
PermissionDenied | — | A runtime permission required to connect was denied. |
PairingFailed | — | Pairing / handshake with the device failed. |
RegistrationRequired | — | The install must register / authenticate before it can connect. |
TransportFailure | code: String, message: String | A native transport-layer failure surfaced while connecting. |
Capture errors
CaptureError
Returned by glasses.camera.capturePhoto() / captureVideo().
| Variant | Payload | Meaning |
|---|---|---|
NotConnected | — | — |
PermissionDenied | — | — |
ThermalCritical | — | — |
HingesClosed | — | — |
CoexistenceBlocked | — | — |
StreamPaused | — | The user paused the camera with the glasses' capture button (temple tap), so the live stream this capture needs is held, not flowing. |
DisabledByUser | toggle: String | A user-facing toggle is gating this capture; toggle is the toggle key (e.g. camera_streaming_enabled) so a handler can explain it. |
PlatformError | code: String, message: String | A native-origin capture failure — structured code + message. |
Audio errors
AudioError
Returned by glasses.audio.recordDiscrete() / speak().
| Variant | Payload | Meaning |
|---|---|---|
NotConnected | — | — |
PermissionDenied | — | — |
CoexistenceBlocked | — | — |
DisabledByUser | toggle: String | As CaptureError.DisabledByUser — a toggle (e.g. audio_capture_enabled). |
PlatformError | code: String, message: String | — |
Transport errors
TransportError
Surfaced by the underlying transport (simulator WebSocket or Meta DAT). WebsocketClosed.code is the WebSocket close code.
| Variant | Payload | Meaning |
|---|---|---|
WebsocketClosed | code: i32, reason: Option<String> | — |
HandshakeFailed | reason: String | — |
SchemaMismatch | server_version: String, client_version: String | — |
Timeout | — | — |
HardwareUnavailable | reason: String | — |
PlatformError | code: String, message: String | — |
The umbrella type
ExtentosError
ExtentosError wraps the four per-area errors plus a catch-all, for APIs that surface any failure.
| Variant | Payload | Meaning |
|---|---|---|
Connect | inner: ConnectError | — |
Capture | inner: CaptureError | — |
Audio | inner: AudioError | — |
Transport | inner: TransportError | — |
Unexpected | message: String | — |
Meta DAT device-session errors
DeviceSessionError
Surfaced by the Meta DAT bridge (RealMetaTransport) when starting a device session on real hardware.
| Variant | Payload | Meaning |
|---|---|---|
NoEligibleDevice | — | — |
PlatformError | code: String, message: String | — |
Assistant errors (Phase 4)
The Phase-4 assistant runtime (glasses.assistant.*) uses a shell-level AssistantError type (not a Rust core enum) with the same six variants on both platforms: a Kotlin sealed class thrown wrapped in AssistantException (com.extentos:glasses, since 1.4.0 — see SDK install) and a Swift AssistantError enum in GlassesCore (lowerCamelCase cases — .noApiKey, .providerError(code:message:)).
| Variant | Payload | Meaning |
|---|---|---|
NoApiKey | — | The Extentos managed gateway isn't reachable. Legacy name: there is no API key to supply — the assistant always runs on the managed gateway. Beta and production builds attest automatically (Play Integrity / App Attest) and need no setup. A sideloaded development build cannot attest, so it reaches the gateway one of two other ways — bound to a browser-simulator session, or through the dev-tier project-key lane. If you hit this on real hardware from a debug build, that binding is what's missing: see how the gateway identifies a caller. |
AlreadyActive | — | An assistant session is already active (the runtime is singleton-active). |
SessionEnded | — | start() was called on a session that has already stopped. |
NotReady | — | wake / sleep / say / etc. called on an Idle or non-Active session. |
NetworkError | cause: Throwable | A network failure reaching the gateway or provider. |
ProviderError | code, message | The upstream AI provider returned an error. |
There is no DisplayError
Display (glasses.display.*) has no returned error type — show() degrades gracefully and never throws (a transport with no display path simply no-ops). Display delivery problems surface as runtime log events on glasses.runtime.events (display.video_delivery_failed, display.image_delivery_failed, display.video_error) and on the errors chip in the simulator event log (they are warn severity). See the display capability docs.
Related
Reference
Generated API reference — the Android SDK (Dokka), iOS SDK (DocC), MCP server tools (JSON Schema), and a flat error-code index for troubleshooting.
Android SDK
Add Extentos to your Android app via Gradle. Smart-glasses capabilities for Meta Ray-Ban, Android 12+ (API 31), Kotlin, coroutines.
Troubleshooting
Symptom-shaped fixes. Find your symptom, get the cause and the fix, with cross-links to error reference.
Permissions
Extentos derives Android permissions and iOS Info.plist keys from the capabilities your handler uses, plus the always-required Bluetooth and Meta DAT keys.
MCP tools reference
The complete, always-current catalog of @extentos/mcp-server tools — 38 deterministic tools across 10 categories for discovering smart-glasses capabilities, scaffolding native iOS/Android integrations, driving the browser simulator, and gating production readiness. Generated from the live tool registry.
Android API reference
Symbol-level reference for the Extentos Android SDK — ExtentosGlasses, ExtentosConfig, every typed sub-client, the assistant builder, and the core data types, with exact Kotlin signatures.