Description
Hitting the same crash signature as #4835 in alpha.90 production build (not dev mode). The fix from #4835 (commit 464659b — `GetController() != nil` guards in `webview_window_windows.go`) is present in our build, but the check and the subsequent `Focus()` call are non-atomic: in our crash trace the controller has been torn down between the guard at line 1023 and the call at line 1028.
Stack trace (production launcher.log, ~4 s after `App.Run`)
```
[WebView2 Error] The parameter is incorrect.
1: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).errorCallback
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:151
2: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).Focus
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:575
3: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).focus
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1028
4: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).WndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1546
5: github.com/wailsapp/wails/v3/pkg/application.(*windowsApp).wndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/application_windows.go:303
```
(Identical shape to the trace in #4835, just from a production binary instead of `wails3 dev` hot-reload.)
Race
`v3/pkg/application/webview_window_windows.go` alpha.90:
```go
1009: func (w *windowsWebviewWindow) focus() {
...
1023: if w.chromium.GetController() == nil {
1024: return
1025: }
// ── another goroutine can tear the controller down here ──
1028: w.chromium.Focus() // crashes when controller is now nil/destroyed
}
```
The other three `chromium.Focus()` call sites in the same file (lines 884–885, 896–897, 945–946) have the same shape — `GetController() != nil` then call — so the same TOCTOU window exists for each.
Trigger
Not deterministic — surfaces ~1 in 10 cold launches of a Wails v3 launcher on Windows 11, ~4 s after `App.Run`. The window message landing in `WndProc` while WebView2's controller is still initialising seems to be the trigger. dev hot-reload (the #4835 reproducer) is not involved.
Suggested fix direction
- Snapshot the controller pointer under `w.chromium`'s lock inside `focus()` (and the other three sites) and call `Focus()` only on the snapshot, OR
- Defer focus messages until the controller has finished initialising (e.g. queue them and drain after `WebView2 Environment created successfully` fires).
Either keeps the fix local to the affected call sites without changing the broader controller lifecycle.
Versions
- Wails v3: `v3.0.0-alpha.90`
- Windows 10/11
- WebView2 runtime: whatever Windows ships
- Build: production (`-tags production -H windowsgui`), tag-triggered release workflow
Cross-ref: #4835 (closed, partial fix landed in 464659b — covers nil controller but not the race).
Description
Hitting the same crash signature as #4835 in alpha.90 production build (not dev mode). The fix from #4835 (commit 464659b — `GetController() != nil` guards in `webview_window_windows.go`) is present in our build, but the check and the subsequent `Focus()` call are non-atomic: in our crash trace the controller has been torn down between the guard at line 1023 and the call at line 1028.
Stack trace (production launcher.log, ~4 s after `App.Run`)
```
[WebView2 Error] The parameter is incorrect.
1: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).errorCallback
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:151
2: github.com/wailsapp/wails/webview2/pkg/edge.(*Chromium).Focus
github.com/wailsapp/wails/webview2@v1.0.24/pkg/edge/chromium.go:575
3: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).focus
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1028
4: github.com/wailsapp/wails/v3/pkg/application.(*windowsWebviewWindow).WndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/webview_window_windows.go:1546
5: github.com/wailsapp/wails/v3/pkg/application.(*windowsApp).wndProc
github.com/wailsapp/wails/v3@v3.0.0-alpha.90/pkg/application/application_windows.go:303
```
(Identical shape to the trace in #4835, just from a production binary instead of `wails3 dev` hot-reload.)
Race
`v3/pkg/application/webview_window_windows.go` alpha.90:
```go
1009: func (w *windowsWebviewWindow) focus() {
...
1023: if w.chromium.GetController() == nil {
1024: return
1025: }
// ── another goroutine can tear the controller down here ──
1028: w.chromium.Focus() // crashes when controller is now nil/destroyed
}
```
The other three `chromium.Focus()` call sites in the same file (lines 884–885, 896–897, 945–946) have the same shape — `GetController() != nil` then call — so the same TOCTOU window exists for each.
Trigger
Not deterministic — surfaces ~1 in 10 cold launches of a Wails v3 launcher on Windows 11, ~4 s after `App.Run`. The window message landing in `WndProc` while WebView2's controller is still initialising seems to be the trigger. dev hot-reload (the #4835 reproducer) is not involved.
Suggested fix direction
Either keeps the fix local to the affected call sites without changing the broader controller lifecycle.
Versions
Cross-ref: #4835 (closed, partial fix landed in 464659b — covers nil controller but not the race).