GopeedLab/gopeed · error
webview is not initialized
Error message
webview is not initialized
What it means
dispatch() reads p.view right after the closed check; if the native webview pointer is still nil it bails with this error. p.view is only assigned inside start()'s run closure (webview.New / NewHeadless), so a nil view means the page was used before startup ran to that point — or startup failed/timed out before assignment.
Source
Thrown at internal/webview/goprovider/provider.go:430
if urlValue, ok := stateMap["url"].(string); ok {
state.URL = urlValue
}
if readyValue, ok := stateMap["readyState"].(string); ok {
state.ReadyState = readyValue
}
return state, nil
}
func (p *pageWrapper) dispatch(fn func(w webview.WebView) error) error {
p.mu.Lock()
if p.closed {
p.mu.Unlock()
return fmt.Errorf("webview page is closed")
}
w := p.view
p.mu.Unlock()
if w == nil {
return fmt.Errorf("webview is not initialized")
}
done := make(chan error, 1)
w.Dispatch(func() {
done <- fn(w)
})
return <-done
}
func (p *pageWrapper) nativeCookies() ([]nativeCookieJSON, error) {
type cookieGetter interface {
GetCookies(url string) ([]webview.Cookie, error)
}
var cookies []webview.Cookie
err := p.dispatch(func(w webview.WebView) error {
getter, ok := w.(cookieGetter)
if !ok {View on GitHub (pinned to 7b7327ffb3)
Solutions
- Always await the provider's Open/start call and require err == nil before any page operation
- If Open returned 'webview startup timeout', abort that page entirely — do not retry operations on it
- Wrap page usage so it cannot begin before initialization completes (channel or once-init)
Example fix
// before
page := provider.NewPage(opts)
page.Goto(url, gotoOpts) // "webview is not initialized" — start() not finished
// after
page, err := provider.NewPage(opts)
if err != nil {
return err // includes startup timeout; page must not be used
}
page.Goto(url, gotoOpts) Defensive patterns
Strategy: validation
Validate before calling
// Only hand out a page after successful initialization
var (
pageCh = make(chan enginewebview.Page, 1)
errCh = make(chan error, 1)
)
func openPage(opts enginewebview.BrowserOptions) (enginewebview.Page, error) {
select {
case p := <-pageCh:
return p, nil
case err := <-errCh:
return nil, err // includes startup timeout: never use the page afterwards
}
} Try / catch
page, err := provider.NewPage(opts)
if err != nil {
return err // do NOT proceed: p.view may be nil -> "webview is not initialized"
}
if err := page.Goto(url, gotoOpts); err != nil {
if strings.Contains(err.Error(), "webview is not initialized") {
return fmt.Errorf("page used before successful open: %w", err)
}
return err
} Prevention
- Make page construction synchronous in your code: no caller runs before Open returns nil
- After any startup error, discard the wrapper entirely
- Guard against accidental use by setting references to nil after failed opens
When it happens
Trigger: Calling Goto/Eval/AddInitScript immediately after constructing the wrapper without waiting for the start/Open call to return; continuing to use the page after a 'webview startup timeout' (error 107) where run() never got far enough to set p.view.
Common situations: Fire-and-forget construction in ported code (older versions may have blocked differently); ignoring the error from start/Open and proceeding; races between an eager caller and the goroutine that boots the webview.
Related errors
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/f158307e87e229d3.
Report an issue: GitHub.