Skip to content

Fix a crash when a sidebar workspace drag ends (from #20015) - #20018

Merged
austinywang merged 2 commits into
mainfrom
fix-sidebar-reorder-dragging-ended
Oct 12, 2026
Merged

austinywang merged 2 commits into
mainfrom
fix-sidebar-reorder-dragging-ended

Conversation

@austinywang

@austinywang austinywang commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #20015. That fix made sidebar workspace reorder work again, but it crashes when the drag ends over the sidebar.

Cause

In #20015, SidebarBonsplitTabWorkspaceDropView forwards draggingEnded(_:) to SidebarWorkspaceReorderDropView. That view doesn't override the method, and NSView doesn't implement draggingEnded: at runtime: NSView.instancesRespond(to: "draggingEnded:") is false. Swift still compiles the call because the optional NSDraggingDestination requirement is imported onto NSView, so at runtime it throws NSInvalidArgumentException: unrecognized selector. AppKit sends draggingEnded: to the last destination that responds to it, and the Bonsplit overlay does, so ending a row drag over the sidebar hits this path. A correctness review subagent found it after #20015 merged.

Fix

  • For sidebar reorder drags, the overlay now ignores draggingEnded instead of forwarding it. That matches how things worked before Drop a sidebar workspace onto a pane to merge its tabs #18837, when AppKit skipped the reorder view for this call.
  • reorderDestination is now typed as SidebarWorkspaceReorderDropView.

Tests

workspaceRowDragOverBonsplitOverlayStillReorders now also calls bonsplit.draggingEnded(sender). The test commit comes before the fix. On that commit the call throws. Neither result was run locally, because local xcodebuild tests aren't allowed here. Hosted CI provides the green result.

Changelog

  • Fixed: Ending a workspace drag in the sidebar no longer crashes.

🤖 Generated with Claude Code


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


Summary by cubic

Fixes a crash when ending a workspace row drag over the sidebar. The Bonsplit overlay forwarded draggingEnded: to the reorder drop view, which doesn't implement it, so AppKit raised an unrecognized selector exception. The overlay now swallows the call for sidebar reorder drags, and reorderDestination is typed as SidebarWorkspaceReorderDropView.

Written for commit 3e3237d. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue that could cause unexpected behavior when ending a drag while rearranging workspaces in the sidebar. Drag-end events are now handled by the visible drop target, while other drag interactions continue to work as before.

austinywang and others added 2 commits October 12, 2026 14:40
Fails on main: #20015 forwards draggingEnded: to the reorder view, which
does not implement it, so AppKit raises an unrecognized selector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Bonsplit overlay forwarded draggingEnded: to the reorder view, which
does not implement it. Swallow it for reorder drags, as AppKit did before
#18837 when the reorder view was the destination, and type the
destination as the reorder view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: b4ac8f23-468a-4b34-9601-dc92c5cc9a4e

📥 Commits

Reviewing files that changed from the base of the PR and between bd83c36 and 3e3237d.


📒 Files selected for processing (2)
  • Sources/Sidebar/SidebarBonsplitTabWorkspaceDropView.swift
  • cmuxTests/SidebarWorkspaceReorderDropOverlayHitTestingTests.swift

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.



📝 Walkthrough

Walkthrough

The sidebar reorder destination now uses SidebarWorkspaceReorderDropView. When a reorder destination exists, draggingEnded returns without forwarding the callback. The overlay hit-testing test checks this behavior.

Changes

Sidebar reorder drag handling

Layer / File(s) Summary
Reorder destination and drag callback
Sources/Sidebar/SidebarBonsplitTabWorkspaceDropView.swift, cmuxTests/SidebarWorkspaceReorderDropOverlayHitTestingTests.swift
The destination property and lookup use SidebarWorkspaceReorderDropView. draggingEnded returns when a reorder destination exists. The test calls draggingEnded on the overlay and documents that the callback is not forwarded to the underlying reorder view.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix


Merge Risk: ⚪ Minimal · up to 3e323

The overlay safely completes sidebar reorder drags without forwarding an unsupported callback, and the inspected drop path remains intact. No actionable merge risk is supported.

Pre-merge checks · Passed 24 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (24 passed)
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the primary change: preventing a crash when a sidebar workspace drag ends.
Description check Passed The description explains the crash, root cause, fix, regression test, testing limitation, and changelog entry. It omits the template's Proof and Checklist sections, but the core review information is …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Cmux Cloud Persistent Session And Early Input Passed PASS. The pull request changes only sidebar drag-drop handling and its regression test. It does not create or modify Cloud terminal clients, transports, readiness gates, input ownership, snapshots, au…
Cmux Swift Actor Isolation Passed The production diff only narrows reorderDestination to the existing @MainActor SidebarWorkspaceReorderDropView and changes drag-end forwarding. It introduces no implicit value-model or service-p…
Cmux Swift Blocking Runtime Passed The production diff only changes the reorder destination type and prevents forwarding draggingEnded; it adds no semaphore, blocking wait, sleep, delayed dispatch, polling, main-queue sync, or manual…
Cmux Browser Automation Off-Main Passed The pull request changes only sidebar drag-and-drop handling and its regression test. It does not change browser socket automation, browser.* command routing, socketWorkerMethods, `processV2Comman…
Cmux Expensive Synchronous Load Passed PASS: The production diff only narrows reorderDestination to SidebarWorkspaceReorderDropView and stops forwarding draggingEnded. It adds no agent-history loader, file read, directory scan, JSON/…
Cmux Cache Substitution Correctness Passed PASS: The production diff only changes drag-destination typing and prevents forwarding draggingEnded to the reorder view. It does not replace an authoritative read with a cached or opportunistic val…
Cmux No Hacky Sleeps Passed PASS. The pull request changes only Swift production code and Swift tests. It introduces no TypeScript, JavaScript, shell, or build/runtime-script sleeps, timers, polling, delayed dispatch, or wall-cl…
Cmux Algorithmic Complexity Passed PASS — The production diff changes a stored reference type and adds an early-return branch in draggingEnded. It adds no collection scan, nested iteration, sorting, filtering, join, or algorithm chan…
Cmux Swift Concurrency Passed PASS. The diff adds no legacy async pattern covered by the check. It changes AppKit drag callbacks, narrows the reorder destination type, and adds a test call to draggingEnded. These are AppKit/XCTe…
Cmux Swift @Concurrent Passed The diff changes only synchronous drag-routing code and a synchronous @MainActor test. It adds no async, nonisolated async, or @concurrent declarations or call sites. Existing async tests and `D…
Cmux Swift Package Boundaries Passed PASS: The only production change is in SidebarBonsplitTabWorkspaceDropView, an NSView AppKit drag-and-drop bridge. It changes the reorder destination type and prevents forwarding draggingEnded t…
Cmux Swiftpm Lockfiles Passed PASS: The PR changes only two Swift source/test files. It does not modify a Package.swift dependency, any package .gitignore, an Xcode project package reference, or a Package.resolved lockfile. The Sw…
Cmux Swift Logging Passed PASS: The pull request adds no production logging and does not materially change existing logging. The Swift diff changes drag routing and adds a test assertion/comment only. Existing dlog calls rem…
Cmux User-Facing Error Privacy Passed The production change affects sidebar drag-event routing, which is reachable through a user sidebar drag, but it adds no user-facing error, alert, command output, API body, or recovery text. The only …
Cmux Full Internationalization Passed PASS: The pull request changes drag-routing behavior and adds a regression test. The only added text is developer-only comments, and the test change is explicitly allowed. No user-facing Swift, web, m…
Cmux Swiftui State Layout Passed PASS: The pull request changes only SidebarBonsplitTabWorkspaceDropView, an NSView AppKit bridge, and a test. The diff adds no SwiftUI view, ObservableObject/@Published state, geometry measure…
Cmux Architecture Rethink Passed PASS: The diff is a small local AppKit callback fix. It changes the destination type to the concrete SidebarWorkspaceReorderDropView and prevents forwarding draggingEnded, which that view does not…
Cmux Swift Auxiliary Window Close Shortcuts Passed The PR changes drag-destination routing and a test-only drag fixture. It does not add or materially change a user-visible standalone NSWindow, NSPanel, NSWindowController, SwiftUI Window, or WindowGro…
Cmux Source Artifacts Passed The pull request changes only two intentional source-control paths: a hand-written Swift source file and its Swift regression test. The diff adds no logs, screenshots, recordings, temporary or cache d…
Cmux No Test Or Debug Seam In Production Source Passed The PR adds no test or debug seam to production source. The only production file changed is Sources/Sidebar/SidebarBonsplitTabWorkspaceDropView.swift; its additions change the reorder destination ty…

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@austinywang

Copy link
Copy Markdown
Contributor Author

Correctness review (subagent): this addresses the one critical finding on #20015 (the forwarded draggingEnded: crash). The reviewer found no other issues. I re-checked that prepareForDragOperation:, draggingExited: and concludeDragOperation: all have NSView runtime implementations, so only draggingEnded: needed this change.

@austinywang
austinywang merged commit 570b668 into main Oct 12, 2026
63 checks passed
@austinywang
austinywang deleted the fix-sidebar-reorder-dragging-ended branch October 12, 2026 21:54
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for 3e3237de73, merged 2026-10-12 21:54:34 UTC

  • Not verified at merge: ci-status (not reported), macOS compile admission (in progress)
  • Verified: backend migrations applied, CI fast guards, Fast static checks, GhosttyKit release check, guards (18), linux-preflight, macOS admission gate, plan, web-validation
  • Skipped by policy: admission-placement, apply-production, apply-staging, browser, Claude wrapper regressions, Dogfood build #​${{ github.event.pull_request.number }}, remote-daemon, suite-coverage, swift-package-tests, ui-tests, web, web-build, and 2 more
  • Full suite: runs on main after merge.

Labeled merged-unverified: if main breaks near this merge, look here first.

@github-actions github-actions Bot added the merged-unverified A judging check was not green at merge; see the merge receipt comment label Oct 12, 2026
@austinywang austinywang mentioned this pull request Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-unverified A judging check was not green at merge; see the merge receipt comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant