Skip to content

[Bug]: SwiftUI app stops showing the running turn after a checkpoint-capture error; iOS app keeps updating #13996

Description

@gmelvill

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

  1. Open the same thread in both the SwiftUI TestFlight app (0.1.0, build 52) and the iOS app (1.3.0, build 85) on one iPhone. The host is a Windows desktop.
  2. Send a message. During the turn, the host fails a checkpoint: Checkpoint capture failed — VCS process timed out in GitVcsDriver.checkpoints.captureCheckpoint: git (<repo>) after 30000ms.
  3. Watch both apps while the turn continues.

Expected behavior

The checkpoint failure shows as a notice, and both apps keep streaming and then show the finished reply.

Actual behavior

The SwiftUI app shows the checkpoint failure above the sent message and then no reply; the composer stays in its busy state. The iOS app shows the same turn finishing normally ("Worked for 1m 25s") with the full reply. The turn completed on the host.

Impact

Major degradation or frequent failure

Version or commit

SwiftUI TestFlight 0.1.0 (52); iOS 1.3.0 (85); desktop 0.0.43-nightly.20260927.2344

Environment

iPhone, iOS 27; Windows 11 host; direct connection over Tailscale Serve HTTPS

Logs or stack traces

Host trace: GitVcsDriver.checkpoints.captureCheckpoint took 19–44 s on this host this morning, with several failures at the 30 s limit. The Git commands themselves are fast (git write-tree ~0.03 s in the same repo); the host's per-command process cleanup is slow (a taskkill /T /F of a trivial process tree measured 16 s, with WMI queries taking 14–57 s), so this checkpoint failure recurs on this machine. The client-side issue is that the SwiftUI app stops following the turn after the error, while the iOS app does not.

Workaround

Read the thread in the iOS app.

Activity

  1. juliusmarminge commented on Sep 27, 2026

    @juliusmarminge
    Member

    Triage

    This is a SwiftUI client bug. The Windows checkpoint timeout is real, but it is not what leaves the thread stuck.

    The host is doing what the server already specifies. CheckpointReactor catches a failed GitVcsDriver.checkpoints.captureCheckpoint and appends a checkpoint.capture.failed activity (summary: "Checkpoint capture failed", detail = the VCS timeout). That does not fail the turn. The React Native app is following that: same thread, same host, reply finishes ("Worked for 1m 25s"). The timeout text matches VcsProcessTimeoutError (VCS process timed out in GitVcsDriver.checkpoints.captureCheckpoint: git (<cwd>) after 30000ms). The slow taskkill / WMI cleanup is why this machine hits the 30s limit; it is not a second bug in this report.

    The client that stops is the SwiftUI TestFlight app (0.1.0, build 52), which is apps/swift-ios on t3code/rebuild-mobile-app-swift (157476f1fb), not apps/mobile. On that branch:

    • Every error-tone activity, including checkpoint.capture.failed, becomes a transcript row (NativeActivityNotice). Rows are ordered by createdAt, and parseDate uses Date.distantPast when a timestamp does not parse, which places the notice above the user bubble.
    • A local send that is still only an optimistic row is appended after the server transcript (addingPendingMessages). If the detail the client has contains the failure notice but not the authoritative user message, the notice sits above the bubble that was just sent, and no assistant reply is in that list. That matches the screenshot-less report.
    • sendMessageResolved does not release the send until a follow-up refreshThread returns. ThreadDetailView.send keeps isSending true for that whole wait, so the composer stays on the busy control while that snapshot read is outstanding. A read blocked behind the same 30s git timeout stays busy for the rest of the turn. The stop control also stays up while session.status is still running (resolveThreadState).
    • reduceActivity does not keep the activity on the thread; the render cache owns it. A decode miss returns .refresh, which clears activeRawThread and drops pending transcript publishes. Until a later snapshot is applied, further detail events are not reduced. The React Native client uses packages/client-runtime threadReducer, which appends the activity and keeps applying later events, so the same turn completes there.

    Not a duplicate. Related unmerged SwiftUI work, none of which mentions this checkpoint trigger: #10758 (release Send before the optional refresh), #10759 (transcript missing the completed reply), #10763 (selected-thread stream goes silent). Those are the right place to fix the client. The host timeout does not need to be fixed for this issue.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions