fix(cloud): stop the snapshot parser trapping on every non-empty snapshot

Merged
AU
2mo ago
+83-1

What broke

cmux NIGHTLY 0.64.22-nightly.3400956733901 crashed three launches in a row on 2026-09-06 (pids 80728, 64295, 79413; EXC_BREAKPOINT on the main thread, all three with the same frames). Each crash landed the moment a Cloud machine finished connecting and sent its first cmux-tui state snapshot, about 30 seconds after launch once the tunnel was healthy.

Root cause

CmuxTuiSnapshotParser.orderedSnapshotRows (added in bdf914a09e) returns rows.enumerated().sorted { … } from a function declared to return [(element: [String: Any], offset: Int)]. EnumeratedSequence yields (offset:, element:), so the labels are reordered. Swift accepts that with only a deprecation warning and compiles it into a runtime array element cast, and that cast fails for every non-empty array:

Could not cast value of type '(offset: Swift.Int, element: Swift.Dictionary<Swift.String, Any>)'
                     to '(element: Swift.Dictionary<Swift.String, Any>, offset: Swift.Int)'

Under -O that is a bare brk #1, which is exactly the trap in the crash reports (disassembly of the shipped binary shows sorted followed by the cast, with the empty-array path returning normally). Empty snapshots never reach the cast, which is why the app looked fine until a machine actually reported a workspace.

A standalone swiftc -O program with the same conversion reproduces the SIGTRAP; changing the return type to the sequence's own label order runs clean.

Fix

Keep (offset:, element:) as the return type. Every caller reads .element and .offset by name, so nothing else changes.

Tests

Two commits so the Commits tab shows the test failing first:

  1. test(cloud): three Swift Testing cases in CmuxTuiSurfaceProviderTests.swift drive workspaces(fromSnapshot:), terminalProjectionTarget(from:), and terminals(fromSnapshot:machine:) with non-empty, indexed rows. They trap without the fix and pin the ordering semantics (explicit index over transport order, focused-first for the projection target).
  2. fix(cloud): the return type change.

No user-facing strings changed, so no localization audit was needed. Local disk on the dev Mac is full, so the app was not rebuilt here; the reproduction is the standalone compiler program plus the shipped binary's disassembly, and CI runs the new tests.

🤖 Generated with Claude Code

https://claude.ai/code/session_013gpMLNXsCY4bmCvkHEavBe


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes the snapshot parser crashing on every non-empty snapshot by aligning the return type with the enumerated() sequence's tuple labels. The crash occurred when a machine connected and reported a workspace; empty snapshots were unaffected.

Adds regression tests covering workspace, terminal projection target, and terminal ordering from non-empty snapshots.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed crashes when processing non-empty terminal snapshots.
    • Corrected snapshot row ordering for workspaces and terminal views, including focused workspaces and rows without explicit indexes.
  • Tests

    • Added regression coverage for snapshot ordering and terminal projection selection.