Skip to content

Stop the git pane's file watch crashing the app - #292

Merged
jiweiyuan merged 1 commit into
mainfrom
fix/git-watcher-crash
Aug 12, 2026
Merged

Stop the git pane's file watch crashing the app#292
jiweiyuan merged 1 commit into
mainfrom
fix/git-watcher-crash

Conversation

@jiweiyuan

Copy link
Copy Markdown
Collaborator

termio dies with SIGTRAP when files change under a repo whose git pane is armed. Crash reports show the FSEvents callback going through swift_task_checkIsolateddispatch_assert_queue_fail in GitPanelModel.armWatcher().

The handler closure is written inside a @MainActor method, so it inherits main-actor isolation. FolderEventStream runs it on a utility queue, and the first main-actor touch — the isBuildProductEvent filter — trips Swift 6's executor check and kills the process. The Task { @MainActor } hop at the end of the handler was correct; the work before it was not.

Fixing only the one call would leave the trap armed for the next caller, so the fix is at the API boundary: FolderEventStream's handler is @Sendable, which forbids isolation inheritance outright. That turns the same mistake into a compile error — it produced exactly the two errors this PR fixes, at the crash site. FileTreeWatcher, the other consumer, already delivers on .main and needed no change.

Hit repeatedly today during ordinary rebuilds: an agent's edit-build-look loop writes into the worktree constantly, which is exactly the trigger.

Verification

swift build clean, swift test 243/243. The compiler reproducing the defect is the regression guard — the isolation is now checked at build time rather than asserted at runtime. Not exercised on a running app; the runtime check is to open the Changes pane and write a file into the repo.

Release Notes:

Fixed a crash when files changed on disk while the git pane was open.

The git pane's FSEvents handler was written inside a `@MainActor` method, so
the closure inherited main-actor isolation — and FSEvents calls it on the
watcher's own utility queue. The first main-actor touch, filtering build
products out of the event batch, hit Swift 6's executor check and took the
whole app down with SIGTRAP. It fires whenever files change under a repo with
the pane armed, so an agent's edit-build-look loop trips it repeatedly.

`FolderEventStream`'s handler is `@Sendable` now, which forbids the silent
isolation inheritance: the hop back to the main actor is the caller's explicit
job, and forgetting it is a compile error rather than a crash on someone's
desk. The pane's path test and its ignored-component set are `nonisolated` —
they are pure string work — and the watched paths are captured immutably.
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
landing Ready Ready Preview Aug 12, 2026 10:26pm

Request Review

@jiweiyuan
jiweiyuan merged commit 50b6572 into main Aug 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant