stablyai/orca · error · EmulatorError
emulator_no_active
emulator_no_active
Error message
No active emulator stream for gesture input
What it means
Thrown by IosEmulatorBackend.gesture when wsUrl is null/empty. The iOS gesture path requires an active WebSocket stream (wsUrl) from the registry, supplied by an attached simulator session; without it there is no channel to deliver the gesture sequence. The backend cannot synthesize a stream, so it throws rather than no-op.
Source
Thrown at src/main/emulator/backends/ios-emulator-backend.ts:153
}
return { available: true, devices, message: 'Ready' }
}
async tap(deviceId: string, x: number, y: number): Promise<void> {
const udid = await this.resolveDeviceId(deviceId)
await this.execServeSim(['tap', x.toString(), y.toString(), '-d', udid])
}
async gesture(
_deviceId: string,
points: EmulatorGesturePoint[],
wsUrl: string | null
): Promise<void> {
if (points.length === 0) {
return
}
if (!wsUrl) {
throw new EmulatorError('emulator_no_active', 'No active emulator stream for gesture input')
}
await sendEmulatorGestureSequence(wsUrl, points)
}
async type(deviceId: string, text: string): Promise<void> {
const udid = await this.resolveDeviceId(deviceId)
await this.execServeSim(['type', text, '-d', udid])
}
async button(deviceId: string, name: string): Promise<void> {
const udid = await this.resolveDeviceId(deviceId)
await this.execServeSim(['button', name, '-d', udid])
}
async rotate(deviceId: string, orientation: string): Promise<void> {
const udid = await this.resolveDeviceId(deviceId)
await this.execServeSim(['rotate', orientation, '-d', udid])
}View on GitHub (pinned to 1136503c6a)
Solutions
- Call startSession(deviceId) first and thread its returned wsUrl into subsequent gesture calls.
- If the session was detached, re-attach (start a new session) before issuing gestures.
- Guard the call: skip gestures when wsUrl is falsy rather than passing null through.
- Verify the iOS backend's session registry is populated for the target simulator.
Example fix
// before: gesture with no active stream await iosBackend.gesture(udid, points, null) // after: attach a session, use its wsUrl const session = await iosBackend.startSession(udid) await iosBackend.gesture(udid, points, session.wsUrl)
Defensive patterns
Strategy: validation
Validate before calling
// Guard gesture calls against a missing stream URL.
function hasStream(wsUrl: string | null): wsUrl is string {
return !!wsUrl && wsUrl !== ''
} Type guard
import { EmulatorError } from '../emulator-errors'
function isNoActiveStream(e: unknown): e is EmulatorError {
return e instanceof EmulatorError && e.code === 'emulator_no_active'
} Try / catch
if (!hasStream(wsUrl)) {
const session = await iosBackend.startSession(deviceId)
wsUrl = session.wsUrl
}
await iosBackend.gesture(deviceId, points, wsUrl) Prevention
- Establish a startSession before issuing gestures and thread its wsUrl.
- Re-attach when the simulator session is detached.
- Skip gesture dispatch when no wsUrl is present rather than passing null.
When it happens
Trigger: gesture(deviceId, points, wsUrl) called with wsUrl null or empty AND points.length > 0 (the empty-points case returns early). wsUrl comes from an attached serve-sim detached session; if no session is attached, the caller has no wsUrl to pass.
Common situations: Calling gesture before startSession has established the detached serve-sim helper (which provides the wsUrl); the simulator session was closed/detached and the registry cleared the wsUrl; attempting gestures on a simulator that was never attached; a routing bug passing null where the registry URL should be.
Related errors
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/d4b714a27290edd7.
Report an issue: GitHub.