Skip to content

wait: a runner restart inside the wait is reported as a capture stall, and outlives the whole budget #2103

Description

@thymikee

A wait that spans a runner restart reports a capture stall, and the restart alone outlives the wait's whole budget. Traced from an iOS smoke failure on an unrelated PR (run 33098577026, #2059, which changes only a dispatch-only workflow and a script it calls).

What the user sees

agent-device wait text "Agent Device Tester" 10000 --platform ios …
COMMAND_FAILED: wait timed out for text: Agent Device Tester
hint: No readable snapshot capture completed before the wait timeout.
      Retry, or use screenshot to inspect the current surface.

The hint points at the surface. The surface was fine.

What actually happened

From the request log (sessions/ios-e2e-smoke-nau/requests/fc627b1104c2bcc2.ndjson):

17:45:01.969  ios_runner_readiness_preflight   findText
17:45:07.124  ios_runner_readiness_preflight   snapshot  durationMs=1029   [error]
17:45:07.124  ios_runner_session_invalidated
17:45:10.605  ios_runner_startup_ensure_booted
17:45:16.872  ios_runner_startup_cleanup_stale_bundles  durationMs=6267
17:45:18.975  ios_runner_startup_ensure_xctestrun       durationMs=2102
17:45:19.075  ios_runner_startup_launch_xcodebuild
17:45:20.259  retry attempt_failed (1/3)
17:45:20.261  retry exhausted (3/3)
17:45:20.262  snapshot_capture  durationMs=14333  backend=xctest  error="request canceled"
17:45:20.274  request_failed    wait timed out for text

A preflight snapshot failed, the runner session was invalidated, and the runner restarted inside the wait. The restart alone spent ~12 s — 6.3 s of it in cleanup_stale_bundles — against a 10 s wait budget. The capture was then canceled, and the failure was reported as if nothing readable had appeared on screen.

Two separable problems

  1. The wait budget does not account for a restart it did not ask for. A 10 s wait cannot survive a ~12 s runner restart, so any invalidation inside a default-length wait is a guaranteed failure regardless of the app's state. Either the restart should not be charged to the caller's budget, or the wait should extend across it.
  2. The error names the wrong thing. wait_capture_stalled and "no readable snapshot capture completed" send the reader to the app and the screen. The daemon log has ios_runner_session_invalidated and a full restart sequence; that is what should surface. AGENTS.md already says a five-second-plus interaction is a daemon-log question naming exactly these phases — the error should carry that rather than making each reader rediscover it.

Fixing (2) alone would make this class self-diagnosing even if (1) stays as designed.

Frequency

Twice in one working session on unrelated PRs, both during scenario bootstrap: this one, and an Android wait timed out for text: Automation lab with the same wait_capture_stalled hint (run 32977635983). The Android instance was not traced, so I am not claiming the same mechanism — only the same reported symptom, which is part of the point of (2).


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions