stablyai/orca · error · EmulatorError
emulator_device_not_found
emulator_device_not_found
Error message
"${deviceOrName}" is not a running device or a known AVD. What it means
Thrown by bootAndroidDevice when the requested deviceOrName is neither a currently running adb serial nor an entry in `emulator -list-avds`. The check exists specifically so a stale/offline serial cannot launch an invalid `-avd` invocation and waste the entire boot timeout. It is an early-fail guard executed before any emulator process is spawned.
Source
Thrown at src/main/emulator/android/android-avd-boot.ts:36
export async function bootAndroidDevice(
runner: AndroidCommandRunner,
sdk: AndroidSdkPaths,
deviceOrName: string,
options: AndroidBootOptions
): Promise<string> {
const running = await listRunningAdbDevices(runner, sdk)
if (running.some((device) => device.serial === deviceOrName)) {
return deviceOrName
}
const existing = await findRunningAvdSerial(runner, sdk, deviceOrName, running)
if (existing) {
return existing
}
// Validate the target is a real AVD before spawning, so a stale/offline serial
// doesn't launch an invalid `-avd` and burn the full boot timeout.
const avds = parseAvdList((await runner(sdk.emulator, listAvdsArgs)).stdout)
if (!avds.includes(deviceOrName)) {
throw new EmulatorError(
'emulator_device_not_found',
`"${deviceOrName}" is not a running device or a known AVD.`
)
}
const known = new Set(running.map((device) => device.serial))
launchAvd(sdk.emulator, deviceOrName)
return waitForNewBootedSerial(runner, sdk, deviceOrName, known, options)
}
// Launches the emulator with spawn (NOT the command runner: execFile would kill
// the long-running, verbose emulator at its timeout / stdout maxBuffer). It is
// NOT detached: DETACHED_PROCESS gives the console-subsystem emulator no console,
// so it (and its qemu/netsim children) pop their own visible one. windowsHide
// gives it a hidden console instead; unref lets the app exit without waiting, and
// managed emulators are shut down on quit anyway. -no-window keeps it headless.
function launchAvd(emulatorPath: string, avdName: string): void {
const child = spawn(emulatorPath, [...bootAvdArgs(avdName), '-no-window'], {
stdio: 'ignore',View on GitHub (pinned to 1136503c6a)
Solutions
- List valid targets first: run `emulator -list-avds` and `adb devices`, then pass an exact AVD name or running serial.
- If you intended a serial, boot the corresponding AVD first or ensure the emulator process is running.
- Verify ANDROID_HOME/ANDROID_AVD_HOME point at the directory holding the AVD ini files.
- Recreate the AVD with avdmanager if it was deleted.
Example fix
// before: passing a guessed name
await bootAndroidDevice(runner, sdk, 'Pixel7', opts) // not a real AVD
// after: discover then boot
const avds = parseAvdList((await runner(sdk.emulator, listAvdsArgs)).stdout)
const name = avds.find(a => a.startsWith('Pixel'))
if (!name) throw new Error(`no matching AVD; available: ${avds.join(', ')}`)
await bootAndroidDevice(runner, sdk, name, opts) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the target exists as an AVD before invoking boot.
import { listAvdsArgs, parseAvdList } from './avd-manager'
import { listRunningAdbDevices } from './android-device-inventory'
async function resolveBootTarget(runner, sdk, name: string): Promise<string | null> {
const running = await listRunningAdbDevices(runner, sdk)
if (running.some(d => d.serial === name)) return name
const avds = parseAvdList((await runner(sdk.emulator, listAvdsArgs)).stdout)
return avds.includes(name) ? name : null
} Type guard
import { EmulatorError } from '../emulator-errors'
function isDeviceNotFound(e: unknown): e is EmulatorError {
return e instanceof EmulatorError && e.code === 'emulator_device_not_found'
} Try / catch
try {
await bootAndroidDevice(runner, sdk, target, opts)
} catch (e) {
if (e instanceof EmulatorError && e.code === 'emulator_device_not_found') {
const avds = parseAvdList((await runner(sdk.emulator, listAvdsArgs)).stdout)
throw new Error(`Unknown target '${target}'. Available AVDs: ${avds.join(', ')}`)
}
throw e
} Prevention
- Always source device/AVD names from `emulator -list-avds`, never hand-typed.
- Verify ANDROID_HOME/ANDROID_AVD_HOME point at the AVD directory.
- Re-list AVDs after creating or deleting with avdmanager.
When it happens
Trigger: bootAndroidDevice(runner, sdk, deviceOrName, options) where deviceOrName is not in listRunningAdbDevices serials, not resolvable via findRunningAvdSerial, AND not present in parseAvdList of the emulator's AVD list. Common form: typo'd AVD name, a serial that belonged to a now-disconnected device, or an AVD that was deleted via avdmanager.
Common situations: User passes a device nickname or partial name that doesn't match the AVD's registered name; the AVD was created under a different ANDROID_AVD_HOME; emulator binary missing so list-avds returns empty; CI cache wiped ~/.android/avd; referencing an emulator-5554 serial after the emulator was killed.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/8925c55f863837d4.
Report an issue: GitHub.