Skip to content

fix(windows): upgrade Tauri to prevent keyboard/focus reentry deadlock #2817

Closed

Description

@mblua

Problem

AgentsCommander 0.41.0 on Windows VM204 stopped delivering GUI IPC at 2026-10-01 03:19 UTC-03 while renderer timers/frames and backend workers remained alive. The preserved renderer recorded 41,019 pending calls.

Unwinding the live backend dump using its own x64 unwind metadata, and checking the checksum-matched tao 0.34.8 source, localized a main-thread self-deadlock: WM_KEYUP handling calls PeekMessageW while keyboard input-state locks remain held; a reentrant WM_KILLFOCUS requests a lock already held by that same thread. The original source of the Shift/focus messages remains unknown; reproduction has not yet run.

Intended change

Update the Rust Tauri dependency to 2.12.1, resolving tao 0.37.1 and its compatible runtime/webview dependencies. The published tao 0.37.1 source removes this observed mechanism: per-window builders, peeks outside input locks, and ordered pending events. This claim is based on the published source, not literal identity with upstream PR tao#1215.

Read-only resolver dry-run succeeded; existing plugins remain pinned; current Rust toolchains exceed the new declared MSRV. Compilation and application behavior are unverified. Expected application change is src-tauri/Cargo.lock; Cargo.toml and application APIs are not expected to change. Any required API migration must be reviewed and added to the plan before implementation.

Acceptance and verification

  • Confirm the resolved tao source lacks the observed lock-held peek/reentry route.
  • Build/check AC and run relevant Rust and frontend suites on the updated dependency graph.
  • Validate a bounded Windows regression harness with the old version as positive failure control and the new version as success control; include a negative control. Use only a private test window and targeted messages, with no global keyboard injection.
  • Review focus, geometry, detached terminals, keyboard/IME, shortcuts and WebView2 regressions appropriate to the dependency update.
  • Review the complete lockfile delta and compatibility of Invoke, WebviewWindowBuilder and the test feature.
  • Required CI, independent adversarial review and PR landing must pass; never claim a merely resolved dependency graph is a working fix.

Scope boundaries

No application-version bump, release, installation, restart of the frozen VM204 app, unrelated synchronous-command refactor, IPC polling mitigation, diagnostic heartbeat, or sharing memory dumps externally. Interactive tests require the user's authorization before delegation. Any fallback backport requires a separately reviewed decision after demonstrated dependency incompatibility.

Evidence

Local shared evidence: room-17-ac-dev-team-v4/room-shared/incident-20261001, including rust-source-findings.md, rust-source-findings-adenda3.md and dump/unwind hashes. Investigation proposal: .ac/plans/vm204-ipc-hang-investigation-proposal.md. No dumps are uploaded to GitHub.

Related upstream: tauri-apps/tao#1349 and tauri-apps/tao#1215. Earlier AC #1652 delivered diagnostics; it did not establish this incident's fix.

User authorized issue creation and resolution on 2026-10-01. Delivery plan review and required specialist gates precede application edits.

Activity

  1. added
    bugSomething isn't working
    windowsAffected platform: the behaviour occurs on or is specific to Windows
    on Oct 1, 2026
  2. mblua commented on Oct 1, 2026

    @mblua
    OwnerAuthor

    Technical scoring (ceremony excluded)

    Category Score Anchor and evidence
    Scope footprint 5 Expected one generated lockfile plus regression harness; limited physical edits.
    Diagnosis difficulty 1 Cause now localized by dump and exact source; completed forensics are not remaining diagnosis.
    Domain knowledge 15 Win32 reentrancy, lock ownership and keyboard event ordering require specialized care.
    Solution-space ambiguity 3 Published version demonstrably removes the route; update chosen, fallback not in scope.
    Blast radius 12 Shared native window and webview path affects focus, DPI, IME and terminals; normal rollback.
    Dependency load 14 Tauri/runtime/tao/wry and platform transitives change together.
    Verification difficulty 20 New bounded interleaving harness needs old-version positive failure control; a green alone is insufficient.
    State and compatibility 10 Existing UI/session behavior and pinned plugin/API compatibility must remain valid; no schema migration.
    Concurrency 19 Same-thread reentrancy and sent-message timing are the actual defect.
    Environment and tooling 10 Windows-specific native window validation and Rust toolchain/build environment.

    Raw sum: 109. Final: round((109-10)/190*99)+1 = 53/100.

    Delivery: Full (architectural/concurrency and shared platform dependency scope raises the nominal Lite band). Architect writes plan, Rust and Grinch independently review matching digest. Vetoes: verification >=8 requires Grinch review of proof; blast radius >=12 requires full file-impact approval tables; state >=10 and concurrency >=10 require architect; environment >=8 requires written developer environment risk before code changes.

    Excluded ceremony: issue/branch/PR creation, delegation, consensus rounds, waiting for CI, merge/cleanup and version/release bookkeeping. No application release or installation requested.

  3. mblua commented on Oct 1, 2026

    @mblua
    OwnerAuthor

    Implementation paused: exact-head CI on 1cbade7 identified two directly related omissions from the approved scope: npm/Rust Tauri major.minor mismatch and nested diagnostic fixture semver lock drift. Frozen plan AF49984F50E048E24758AFDD59943332ADFC35FC03BDE457DAE330F008F0FC6B no longer authorizes further edits; a new certified plan and human approval are required. No corrective edits made. Windows CI executed both new tests successfully; positive/negative controls, GUI smoke and excess-send investigation remain open.

    Remaining-delta technical re-score (previous score53/raw109):

    Category Score Anchor and evidence
    Scope footprint 5 Few files moving together: npm lock, fixture lock and reversible diagnostic instrumentation, below module scope10.
    Diagnosis difficulty 18 Intermittent excess-send not reproduced in baseline5/head6 quiet runs; near20 load-only anchor; CI compatibility causes known.
    Domain knowledge 12 Build resolution/version contracts and cancellation/flush ownership exceed subsystem10 anchor.
    Solution ambiguity 5 Lock fixes largely determined; scratch timing diagnostic still needs architecture decision, below several alternatives10.
    Blast radius 10 Shared frontend dependency/build path; normal rollback possible.
    Dependency integration 14 Rust/npm version alignment, nested offline fixture, frontend/Rust ownership exceed single-library10.
    Verification difficulty 20 Positive/negative controls still required; green detector alone insufficient.
    State compatibility 8 Version compatibility and preserved baseline evidence; no persisted-data migration.
    Concurrency timing 19 Unresolved cancellation/restart/flush ordering and deadlock control timing near20 anchor.
    Environment tooling 18 CI-only packaging/fixture failures plus memory-stopped shared host near20 anchor.

    Raw129. Final round((129-10)/190*99)+1=63. Excluded ceremony: issue/branch/PR handling, waitingCI, review rounds, delegation, messaging, merging, cleanup. Actual CI compatibility diagnosis included in environment. Architect must reassess partition/ownership at the new band; score does not itself dictate a product solution.

  4. mblua commented on Oct 1, 2026

    @mblua
    OwnerAuthor

    D15 natural negative control: executed in CI and failed as designed

    Evidence record for the version-coupling test added on this branch. This is the negative half of the control only; the positive half has not run. No rerun was made.

    Execution

    Verbatim from the job log (colour codes removed)

    2026-10-01T21:33:26.2545647Z      Running tests\tauri_npm_version_coupling.rs (D:\a\AgentsCommander\AgentsCommander\target\debug\deps\tauri_npm_version_coupling-e5bc9d2e305f57c0.exe)
    2026-10-01T21:33:26.2749270Z running 1 test
    2026-10-01T21:33:26.3687337Z test tauri_crate_and_npm_api_share_a_major_minor ... FAILED
    2026-10-01T21:33:26.3692434Z thread 'tauri_crate_and_npm_api_share_a_major_minor' (7676) panicked at src-tauri\tests\tauri_npm_version_coupling.rs:75:5:
    2026-10-01T21:33:26.3695555Z assertion `left == right` failed: #2817: `tauri` 2.12.1 in D:\a\AgentsCommander\AgentsCommander\Cargo.lock and `@tauri-apps/api` 2.10.1 in D:\a\AgentsCommander\AgentsCommander\package-lock.json differ in major.minor. The Tauri CLI aborts `npm run build:prod` and `npm run build:prod:no-bundle` with "Found version mismatched Tauri packages".
    2026-10-01T21:33:26.3697724Z   left: (2, 12)
    2026-10-01T21:33:26.3698035Z  right: (2, 10)
    2026-10-01T21:33:26.3700682Z test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    2026-10-01T21:33:26.4243307Z error: test failed, to rerun pass `--test tauri_npm_version_coupling`
    

    The target binary ran, the named test failed on its own assertion at line 75, and the message names both versions and both lockfiles. It is not a compile error and not a failure of another target.

    Every red job in the two runs, by cause

    Job Cause from its log
    rust-regression the assertion above, and only it
    bundle-validation (run 36926675480), windows-release-cli-smoke Tauri CLI: Found version mismatched Tauri packages ... tauri (v2.12.1) : @tauri-apps/api (v2.10.1)
    terminal-snapshot-portable on windows-latest, ubuntu-latest, macos-15, macos-15-intel diagnostic_fixture_lock_versions_are_a_workspace_subset: fixture lock pins semver 1.0.27, absent from the workspace Cargo.lock

    Three causes, each one a lockfile alignment still pending on this branch. The other nine jobs of the full tier were green.

    Limits

    • Cargo stops at the first failing target, so two integration targets after it did not run on Windows: terminal_snapshot_host.rs and wake_consumption_measure.rs. 27 of 29 ran; the lib suite before them reported 5838 passed; 0 failed; 26 ignored.
    • The coupling test ran on Windows only. The Linux and macOS regression jobs are green but do not run this target.
    • In the same step tao_keyboard_reentrancy reported resolved_tao_is_at_least_0_37_1 ... ok and win_harness::wm_keyup_peek_does_not_deadlock_on_reentrant_wm_killfocus ... ok. That is on this intermediate head, not the final one.
    • One execution, attempt 1.

    Preserved log

    The full rust-regression job log (3413884 bytes) is archived with the team's evidence. SHA-256 0d7957d81dced07fd77a8e1a66a3e25fc55a6eb9181eb3346ac8cf01775ae247. The excerpt above is lines 15829 to 15851 of that file.

  5. mblua commented on Oct 2, 2026

    @mblua
    OwnerAuthor

    CI record for 23c5c2ad: all ten runs green, coupling test positive control executed

    Factual record of the finished CI executions for the current head of PR #2819. It reports what ran. It is not an approval, and it closes nothing.

    Identity

    • Work SHA 23c5c2adb0036fdbad1bdfcf43ac0f87eed4279f: @tauri-apps/api lock entry to 2.12.1, diagnostic fixture lock semver to 1.0.28, plus .github/workflows/g-fe-certification.yml.
    • The pull_request workflows tested merge ref 05eea84037b528d58bcae00e30ff3cf270559eaa: "Merge 23c5c2a… into a6b6280". That base is newer than the main commit the branch was last synced with (c070965368431db38861252e9f9c13f1c8946029).
    • The push workflows, including G-FE certification, ran on the work SHA itself.

    Runs, all completed / success, attempt 1

    Run Workflow Event
    36938954236 PR regression gates, full tier, 16 jobs pull_request
    36938954339 Bundle validation pull_request
    36938950553 G-FE certification push
    36938954414, 36938950555 Lockfile drift check pull_request, push
    36938954326, 36938950472 Version sync check pull_request, push
    36938954216, 36938950501 Validate no plans path pull_request, push
    36938950469 Validate branch name push

    25 jobs, no failed step.

    Coupling test, positive control (job rust-regression 110625715337, windows-latest, colour codes removed)

    2026-10-01T23:32:16.5332632Z      Running tests\tauri_npm_version_coupling.rs (D:\a\AgentsCommander\AgentsCommander\target\debug\deps\tauri_npm_version_coupling-e5bc9d2e305f57c0.exe)
    2026-10-01T23:32:16.5574787Z running 1 test
    2026-10-01T23:32:16.6514805Z test tauri_crate_and_npm_api_share_a_major_minor ... ok
    2026-10-01T23:32:16.6516292Z test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    

    Same target and test as the negative control recorded earlier on this issue, now ok. The two controls ran on different bases (negative on 2ed19c1c, positive on a6b62803); the test file is byte-identical in both.

    Keyboard reentrancy harness, same step

    2026-10-01T23:32:16.5010253Z test resolved_tao_is_at_least_0_37_1 ... ok
    2026-10-01T23:32:16.5300046Z test win_harness::wm_keyup_peek_does_not_deadlock_on_reentrant_wm_killfocus ... ok
    2026-10-01T23:32:16.5301724Z test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
    

    The three earlier failure causes

    • Tauri CLI version check: no "Found version mismatched Tauri packages" in bundle-validation or windows-release-cli-smoke; the bundle job finished 2 bundles.
    • diagnostic_fixture_lock_versions_are_a_workspace_subset: ok on windows-latest, ubuntu-latest, macos-15 and macos-15-intel.
    • Windows cargo test --locked --lib --bins --tests: lib 5841 passed; 0 failed; 26 ignored, 29 of 29 integration targets ran, 0 FAILED result lines.

    G-FE certification run

    Run 36938950553, job 110625703225, artifact g-fe-evidence-23c5c2adb0036fdbad1bdfcf43ac0f87eed4279f (ID 11200070163), ten evidence files retrieved. The five command status lines each record exit 0, and the recorded installed API version is 2.12.1. Certification of this evidence belongs to the frontend owner and is pending.

    Limits

    • The tested base a6b62803 is newer than the branch's sync point; what changed in between has not been classified.
    • One execution each, no rerun. The coupling test and the harness ran on Windows only.
    • These are CI executions. The plan's local gates and the frontend certification are separate and are not claimed here.
    • The harness lines show ok only. No local reproduction of the original deadlock was performed, and no real-runtime check of the new JS API minor exists; npm test exercises mocked seams.
    • The intermittent excess telegram.send_message finding seen locally earlier remains open and unexplained.

    Full logs and run metadata are archived with the team's evidence. rust-regression log SHA-256 35e58ea2d825996bb932e097666560ba6aaa7a940df2d98299b9c9a198de0f23; G-FE job log b6d83cc9acca1c8096b3c0cdc347db03058719bda63eeb463611135b3a7a79f0; manifest 290880f7f46834c9423e890c979db86584a3e11690bcca038557d5fbe1b263d5.

  6. mblua commented on Oct 2, 2026

    @mblua
    OwnerAuthor

    CI record for ae35162b: one run red, nine green. Delivery stopped.

    Factual record of the finished CI executions for the current head of PR #2819. It reports what ran. It is not an approval, it attributes no cause, and it closes nothing.

    Identity

    • Work SHA ae35162b4d703e8b4ae69c9185a00d0cfe834319: merge of main at d9c7db925d406ab77eafd5c326a800db367342d1 into the branch head 23c5c2adb0036fdbad1bdfcf43ac0f87eed4279f.
    • The pull_request workflows tested merge ref f5260672: "Merge ae35162… into d9c7db9". The base tested equals the base the branch was merged with.
    • The push workflows, including G-FE certification, ran on the work SHA itself.

    Runs, all completed, attempt 1

    Run Workflow Event Conclusion
    36952718755 PR regression gates, 16 jobs pull_request failure
    36952718718 Bundle validation pull_request success
    36952715104 G-FE certification push success
    36952718705, 36952715110 Lockfile drift check pull_request, push success
    36952718736, 36952715133 Version sync check pull_request, push success
    36952718756, 36952715109 Validate no plans path pull_request, push success
    36952715112 Validate branch name push success

    25 jobs: 24 success, 1 failure.

    The failure (job rust-regression 110668942790, windows-latest, step cargo test, command cargo test --locked --lib --bins --tests)

    2026-10-02T02:09:08.4941829Z ---- capture::state::tests::contention_is_lock_busy_and_bounded stdout ----
    2026-10-02T02:09:08.4942993Z thread 'capture::state::tests::contention_is_lock_busy_and_bounded' (2192) panicked at src-tauri\src\capture\state.rs:1411:9:
    2026-10-02T02:09:08.4943650Z gave up after 588.4544ms
    2026-10-02T02:09:08.4945765Z test result: FAILED. 5840 passed; 1 failed; 26 ignored; 0 measured; 0 filtered out; finished in 237.27s
    2026-10-02T02:09:14.9830326Z ##[error]Process completed with exit code 1.
    

    The assertion at that line is elapsed <= LOCK_WAIT_BUDGET + Duration::from_millis(150), with LOCK_WAIT_BUDGET at 100 ms: it allows 250 ms and the run measured 588.4544 ms.
    src-tauri/src/capture/state.rs is byte-identical between main at d9c7db92 and this head, and is not a path this branch changes. That is a fact about bytes; no cause is claimed and nothing was rerun.

    What did not run because of it

    • The lib unit-test binary failed, so cargo did not run the Windows integration targets. The coupling test (tauri_npm_version_coupling) and the keyboard reentrancy harness (tao_keyboard_reentrancy) were not executed for this SHA. Their earlier results on 23c5c2ad are historical.
    • Four IS config: canonical HOME for unsuffixed executables, no migration #1850 steps of the same job were skipped.

    The other jobs

    • rust-regression-linux and rust-regression-macos: 0 FAILED result lines.
    • diagnostic_fixture_lock_versions_are_a_workspace_subset: ok on ubuntu-latest, windows-latest, macos-15 and macos-15-intel.
    • Tauri CLI version check: no "Found version mismatched" line in bundle-validation or windows-release-cli-smoke; the bundle job finished 2 bundles.

    G-FE certification run

    Run 36952715104, job 110668930442, artifact g-fe-evidence-ae35162b4d703e8b4ae69c9185a00d0cfe834319 (ID 11203789484, upload digest ac761d0afc051485e672c19b23e7f6735dbca5a3847d9c2f8a96f9929b3e9f53, expires 2026-12-31), ten evidence files retrieved and their nine recorded digests matched. The five command status lines each record exit 0, and the recorded installed API version is 2.12.1. Certification of this evidence belongs to the frontend owner and is pending. A green G-FE run does not lift the red regression run.

    Limits

    • One execution each, no rerun. The red is unexplained.
    • These are CI executions. The plan's local gates and the frontend certification are separate and are not claimed here.
    • No local reproduction of the original deadlock and no real-runtime check of the new JS API minor exist.

    Full logs and run metadata are archived with the team's evidence. rust-regression log SHA-256 18b9efcf31620b7e563d7ef38d8c6ac6d4f66f0c93064b56ed475de8920ba454; G-FE job log bf8173ec07d82ebed7550e074f7983df542dd511df7d3e824f3c69311cfddd23; manifest 3f8fbd80431edc488eb326df5e1ae017ab15cc87e78d84f85b8e54dcd600c836.

  7. mblua commented on Oct 2, 2026

    @mblua
    OwnerAuthor

    CI record for ae35162b, run 36952718755 attempt 2: the one re-executed job is green

    Factual record of one re-execution. It follows the earlier record on this issue of attempt 1, which was red. It is not an approval, it attributes no cause, and it closes nothing.

    What was re-executed

    • One job only: rust-regression (Windows) of the PR regression gates run 36952718755. New job 110686244967, attempt 2, completed / success, 03:02:09Z to 03:40:56Z.
    • The other 15 jobs of the run were not re-executed. They appear in attempt 2 with new job IDs but with their attempt-1 start time, end time and runner. Their success is the attempt-1 result shown again.
    • Attempt 1 and its red job 110668942790 are preserved.

    Identity tested

    • The checkout fetched merge commit f5260672d5b2dda0ce09041ffd48642fdede51c2 by full SHA: "Merge ae35162 into d9c7db9". Same merge commit and base as attempt 1.

    The job

    23 steps, all success, none skipped. cargo test --locked --lib --bins --tests: lib 5841 passed; 0 failed; 26 ignored; 29 of 29 integration targets ran; 57 result lines, none FAILED. The four IS #1850 steps that attempt 1 skipped ran.

    The test that failed in attempt 1

    2026-10-02T03:16:46.7321180Z test capture::state::tests::contention_is_lock_busy_and_bounded ... ok
    

    It passed this time. A passing run prints no elapsed time, so this does not explain the 588.4544 ms measured in attempt 1. That failure remains unexplained.

    Coupling test and keyboard reentrancy harness, now executed for this SHA (colour codes removed)

    2026-10-02T03:26:40.2532640Z test resolved_tao_is_at_least_0_37_1 ... ok
    2026-10-02T03:26:40.2733088Z test win_harness::wm_keyup_peek_does_not_deadlock_on_reentrant_wm_killfocus ... ok
    2026-10-02T03:26:40.2759095Z test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
    2026-10-02T03:26:40.3330583Z test tauri_crate_and_npm_api_share_a_major_minor ... ok
    2026-10-02T03:26:40.3331036Z test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
    

    Limits

    • One re-execution of one job, on Windows only. It shows the job can pass on this merge commit, not why it failed before.
    • The harness lines show ok only. No local reproduction of the original deadlock and no real-runtime check of the new JS API minor exist.
    • These are CI executions. The plan's local gates and the frontend certification are separate and are not claimed here.

    Logs and metadata are archived with the team's evidence. Attempt-2 rust-regression log SHA-256 a1015b17a8588c4c25a327dbab4233f5e5e0dbd81f32b8561ffb0111c88cdefb; manifest 06eefed01dccd9752df91b87cc7d92b6c77e60ee5b3b26d1d3603998ebde04ed.

  8. added a commit that references this issue on Oct 2, 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 isn't workingwindowsAffected platform: the behaviour occurs on or is specific to Windows

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions