Skip to content

Don't panic syncing a browser pane whose navigation failed - #63

Merged
ryanclouser merged 1 commit into
ProjectHax:masterfrom
freddysae0:fix/browser-sync-nil-url
Oct 3, 2026
Merged

ryanclouser merged 1 commit into
ProjectHax:masterfrom
freddysae0:fix/browser-sync-nil-url

Conversation

@freddysae0

Copy link
Copy Markdown
Contributor

Opened by Claude (Claude Code), the AI assistant of @freddysae0, on their behalf.

Fixes #62

Problem

On macOS, a browser pane whose navigation fails (an unresolvable host, being offline, a typo in the URL) aborts muxel a few seconds after launch. The pane is restored on every launch, so muxel crash-loops until someone edits workspace.json by hand.

WKWebView.URL becomes nil once a provisional navigation fails. lb-wry's url_from_webview calls .unwrap() on that value. BrowserView::sync runs inside a GPUI task on the main dispatch queue, so the panic can't unwind and the process gets SIGABRT. The existing .url().ok()? never runs, because the panic happens before any Result is produced. Upstream tauri-apps/wry still has the same unwrap.

Fix

sync now goes through a small committed_url helper:

  • macOS: checks WKWebView.URL (and its absoluteString) before calling wry::WebView::url(). When there is no URL, sync returns None, the same way it already handles other "nothing to sync yet" states. The next tick tries again.
  • Windows: unchanged. WebView2's url() already returns a Result.

There are no behaviour changes for pages that load. One file changed.

Verification

  • cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings and cargo test --workspace all pass.
  • I reproduced the crash end to end in an isolated HOME. The workspace has a single browser pane, browser_enabled = true, and the build was instrumented with temporary eprintln!s that are not part of this PR:
Build browser_url Webview built sync saw URL == nil Result
master https://no-such-host-xyz123.invalid/ yes n/a abort after 4–14 s, url_from_webview panic (5/5 runs)
master https://deploy-preview-17--…netlify.app-/ (the original report) yes n/a abort after 6 s, same panic
this PR https://no-such-host-xyz123.invalid/ yes 12× and 18× alive at 25 s (2/2 runs)
this PR https://deploy-preview-17--…netlify.app-/ yes 10× alive at 25 s
this PR https://example.com/ yes 0× (Some("https://example.com/") on every tick) alive, URL syncs as before

The table only counts runs where the webview was actually created. A few launches from a script never painted the pane, and I left those out because they prove nothing either way.

I built locally without full Xcode, so these binaries used gpui's runtime_shaders feature. That change is local only and not included here.

I also confirmed the nil with a standalone Swift WKWebView probe, with no muxel or wry involved. The URL is set right after load, and is nil about 6 s later for an unresolvable host. For example.com it stays set.

🤖 Generated with Claude Code

On macOS, WKWebView.URL becomes nil once a provisional navigation fails
(unresolvable host, offline, typo). lb-wry's url_from_webview unwraps that
nil, and because BrowserView::sync runs inside a GPUI task on the main
dispatch queue the panic aborts the whole app. The pane is restored on
every launch, so muxel crash-loops until workspace.json is edited by hand.

Check that the webview has a committed URL before asking wry for it, and
treat its absence like any other "nothing to sync yet" tick.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ryanclouser
ryanclouser merged commit 535ba5a into ProjectHax:master Oct 3, 2026
5 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.

macOS: browser pane with a failed navigation aborts muxel on every launch (url_from_webview unwrap)

2 participants