Summary
Surfaced while capturing device footage for a blog post. scroll "bottom" fails deterministically
(3/3) on the Pixel 9 Pro XL API 37 emulator (emulator-5556) with:
COMMAND_FAILED: Android helper returned an invalid gesture viewport
preceded by a helper warning:
android_touch_helper_viewport_session_fallback reason: "unknown session command"
Non-scroll operations (open, get, is, press, back, record) all work normally on this
same emulator/session. This looks like the daemon's session-scoped viewport-detection path issuing
a command the on-device snapshot helper doesn't recognize, and the one-shot fallback that's
supposed to catch that failure also fails to produce a usable gesture viewport.
Repro
open com.android.settings --relaunch
scroll bottom
Result: COMMAND_FAILED: Android helper returned an invalid gesture viewport.
Reproduced on three separate daemon builds, ruling out a build-specific regression:
3fed8acda
a84caa818 (current main HEAD at the time of testing)
d85165842
Environment: Pixel 9 Pro XL API 37 emulator (emulator-5556), on-device snapshot helper
agent-device-android-snapshot-helper-0.19.3.apk.
Root cause (read from source)
readAndroidTouchHelperViewport (src/platforms/android/touch-helper.ts:106-127) first tries a
session-scoped viewport command against the persistent helper:
const sessionHeaders = await runAndroidSnapshotHelperSessionTouchCommand({
deviceKey: prepared.deviceKey,
action: 'viewport',
helper: touchSessionHelperIdentity(prepared.artifact),
timeoutMs: HELPER_VIEWPORT_TIMEOUT_MS,
});
if (sessionHeaders) return readViewportResult(sessionHeaders);
On this emulator/helper combination that command throws, and the catch block logs the
android_touch_helper_viewport_session_fallback warning with the underlying error message as
reason — which is exactly "unknown session command", i.e. the persistent
UiAutomation-instrumentation session (Java: SnapshotInstrumentation, which emits "unknown session command" at
android/snapshot-helper/src/main/java/com/callstack/agentdevice/snapshothelper/SnapshotInstrumentation.java:201)
does not recognize whatever session command the daemon sent for action: 'viewport'.
The catch block then stops the session and falls back to a one-shot instrumentation run
(runOneShotTouchHelper with mode=viewport, same file, ~line 127-135). On this emulator that
fallback also fails to produce a usable viewport, and the caller surfaces the generic:
throw new AppError('COMMAND_FAILED', 'Android helper returned an invalid gesture viewport');
(src/platforms/android/gesture-viewport.ts:13, and the equivalent check in
src/platforms/android/touch-helper.ts:306), which is what scroll (and presumably other
gesture-planned commands that need a viewport) sees.
Since open/get/is/press/back/record don't go through this gesture-viewport resolution
path, they're unaffected — this narrows the bug to the viewport-detection session command
specifically, not the helper or session machinery broadly.
Note
The resulting divergence signature (when this is hit via the replay/differential machinery) has
the same shape as div_plain_1.json already used elsewhere in the wave-3 evidence set. This is
likely related to the existing gesture-viewport / Android-helper-scroll work (see the
android-helper-scroll-attrs-authoritative and android-automation-helper-consolidation lines of
work) — worth checking whether the persistent helper's session-command protocol (post the #1281
single-persistent-helper consolidation) has a gap for the viewport action specifically on this
API level/device combination.
Source leads
src/platforms/android/touch-helper.ts:
readAndroidTouchHelperViewport (~line 106) — session-scoped viewport attempt, catch +
fallback-to-one-shot.
- Line ~124:
phase: 'android_touch_helper_viewport_session_fallback' diagnostic emission.
- Line ~306:
'Android helper returned an invalid gesture viewport' (one-shot fallback also
failing).
src/platforms/android/gesture-viewport.ts:13 — same error string, gesture-plan-level check.
android/snapshot-helper/src/main/java/com/callstack/agentdevice/snapshothelper/SnapshotInstrumentation.java:201
— "unknown session command" source of the fallback's reason.
Repro builds / environment
- Builds tested:
3fed8acda, a84caa818 (main HEAD), d85165842 — all fail identically.
- Emulator: Pixel 9 Pro XL API 37,
emulator-5556.
- Helper:
agent-device-android-snapshot-helper-0.19.3.apk.
Summary
Surfaced while capturing device footage for a blog post.
scroll "bottom"fails deterministically(3/3) on the Pixel 9 Pro XL API 37 emulator (
emulator-5556) with:preceded by a helper warning:
Non-scroll operations (
open,get,is,press,back,record) all work normally on thissame emulator/session. This looks like the daemon's session-scoped viewport-detection path issuing
a command the on-device snapshot helper doesn't recognize, and the one-shot fallback that's
supposed to catch that failure also fails to produce a usable gesture viewport.
Repro
Result:
COMMAND_FAILED: Android helper returned an invalid gesture viewport.Reproduced on three separate daemon builds, ruling out a build-specific regression:
3fed8acdaa84caa818(currentmainHEAD at the time of testing)d85165842Environment: Pixel 9 Pro XL API 37 emulator (
emulator-5556), on-device snapshot helperagent-device-android-snapshot-helper-0.19.3.apk.Root cause (read from source)
readAndroidTouchHelperViewport(src/platforms/android/touch-helper.ts:106-127) first tries asession-scoped viewport command against the persistent helper:
On this emulator/helper combination that command throws, and the catch block logs the
android_touch_helper_viewport_session_fallbackwarning with the underlying error message asreason— which is exactly"unknown session command", i.e. the persistentUiAutomation-instrumentation session (Java:
SnapshotInstrumentation, which emits"unknown session command"atandroid/snapshot-helper/src/main/java/com/callstack/agentdevice/snapshothelper/SnapshotInstrumentation.java:201)does not recognize whatever session command the daemon sent for
action: 'viewport'.The catch block then stops the session and falls back to a one-shot instrumentation run
(
runOneShotTouchHelperwithmode=viewport, same file, ~line 127-135). On this emulator thatfallback also fails to produce a usable viewport, and the caller surfaces the generic:
(
src/platforms/android/gesture-viewport.ts:13, and the equivalent check insrc/platforms/android/touch-helper.ts:306), which is whatscroll(and presumably othergesture-planned commands that need a viewport) sees.
Since
open/get/is/press/back/recorddon't go through this gesture-viewport resolutionpath, they're unaffected — this narrows the bug to the viewport-detection session command
specifically, not the helper or session machinery broadly.
Note
The resulting divergence signature (when this is hit via the replay/differential machinery) has
the same shape as
div_plain_1.jsonalready used elsewhere in the wave-3 evidence set. This islikely related to the existing gesture-viewport / Android-helper-scroll work (see the
android-helper-scroll-attrs-authoritativeandandroid-automation-helper-consolidationlines ofwork) — worth checking whether the persistent helper's session-command protocol (post the #1281
single-persistent-helper consolidation) has a gap for the
viewportaction specifically on thisAPI level/device combination.
Source leads
src/platforms/android/touch-helper.ts:readAndroidTouchHelperViewport(~line 106) — session-scoped viewport attempt, catch +fallback-to-one-shot.
phase: 'android_touch_helper_viewport_session_fallback'diagnostic emission.'Android helper returned an invalid gesture viewport'(one-shot fallback alsofailing).
src/platforms/android/gesture-viewport.ts:13— same error string, gesture-plan-level check.android/snapshot-helper/src/main/java/com/callstack/agentdevice/snapshothelper/SnapshotInstrumentation.java:201—
"unknown session command"source of the fallback'sreason.Repro builds / environment
3fed8acda,a84caa818(main HEAD),d85165842— all fail identically.emulator-5556.agent-device-android-snapshot-helper-0.19.3.apk.