stablyai/orca · critical · EmulatorError
emulator_error
emulator_error
Error message
Android SDK not found. Install Android Studio and set ANDROID_HOME.
What it means
Thrown by AndroidSdkState.require when resolve() returns null — meaning no SDK paths were injected and discoverAndroidSdkFromHost failed to locate one. The constant message directs the developer to install Android Studio and set ANDROID_HOME. This is a hard prerequisite gate: every Android backend method calls requireSdk() which routes here.
Source
Thrown at src/main/emulator/android/android-sdk-state.ts:24
// Resolves the backend's Android SDK. An injected SDK (tests, or an explicit
// null) is fixed; for the real host it re-runs discovery on every call so a
// newly-installed SDK or a changed configured path takes effect without a
// restart. Host discovery is only a few existsSync probes, so this is cheap.
export class AndroidSdkState {
constructor(
private readonly injected: boolean,
private readonly injectedSdk: AndroidSdkPaths | null
) {}
resolve(): AndroidSdkPaths | null {
return this.injected ? this.injectedSdk : discoverAndroidSdkFromHost()
}
require(): AndroidSdkPaths {
const sdk = this.resolve()
if (!sdk) {
throw new EmulatorError('emulator_error', SDK_MISSING)
}
return sdk
}
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Install Android Studio or the command-line tools and set ANDROID_HOME to the SDK root (the folder containing platform-tools/).
- Verify the path actually contains platform-tools/adb, emulator/emulator, and build-tools — discoverAndroidSdkFromHost validates structure, not just existence.
- In CI/containers, export ANDROID_HOME (and ANDROID_SDK_ROOT for older tools) before launching the app.
- If you have a non-standard location, inject it via AndroidSdkState(true, paths) at construction instead of relying on discovery.
Example fix
# before: env unset export PATH=... # after: point at a real SDK export ANDROID_HOME=$HOME/Android/Sdk export ANDROID_SDK_ROOT=$ANDROID_HOME # verify structure ls $ANDROID_HOME/platform-tools/adb $ANDROID_HOME/emulator/emulator
Defensive patterns
Strategy: validation
Validate before calling
// Verify the SDK is discoverable before any Android operation.
function sdkResolved(state: AndroidSdkState): boolean {
return state.resolve() !== null
} Type guard
import { existsSync } from 'node:fs'
function sdkLooksComplete(p: { adb: string; emulator: string }): boolean {
return existsSync(p.adb) && existsSync(p.emulator)
} Try / catch
try {
const sdk = sdkState.require()
} catch (e) {
if (e instanceof EmulatorError && e.code === 'emulator_error' && /Android SDK not found/.test(e.message)) {
throw new Error('Set ANDROID_HOME to a directory containing platform-tools/ and emulator/')
}
throw e
} Prevention
- Set ANDROID_HOME (and ANDROID_SDK_ROOT) in the environment before launch.
- Confirm platform-tools/adb and emulator/emulator exist in the SDK root.
- Inject a known SDK path via AndroidSdkState(true, paths) when discovery is unreliable.
When it happens
Trigger: AndroidSdkState was constructed with injected=false (or injectedSdk=null) and require() is called. discoverAndroidSdkFromHost checked ANDROID_HOME / ANDROID_SDK_ROOT / common install locations and found nothing usable.
Common situations: Fresh CI worker without Android Studio; ANDROID_HOME set to a path that doesn't contain the expected platform-tools/emulator binaries; SDK installed via command-line tools only but PATH/env not configured; a Docker container missing the env var; the SDK directory exists but platform-tools is absent.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/9b50233f83becef2.
Report an issue: GitHub.