{"record":{"id":"f158307e87e229d3","repo":"GopeedLab/gopeed","slug":"webview-is-not-initialized","errorCode":null,"errorMessage":"webview is not initialized","messagePattern":"webview is not initialized","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/webview/goprovider/provider.go","lineNumber":430,"sourceCode":"\tif urlValue, ok := stateMap[\"url\"].(string); ok {\n\t\tstate.URL = urlValue\n\t}\n\tif readyValue, ok := stateMap[\"readyState\"].(string); ok {\n\t\tstate.ReadyState = readyValue\n\t}\n\treturn state, nil\n}\n\nfunc (p *pageWrapper) dispatch(fn func(w webview.WebView) error) error {\n\tp.mu.Lock()\n\tif p.closed {\n\t\tp.mu.Unlock()\n\t\treturn fmt.Errorf(\"webview page is closed\")\n\t}\n\tw := p.view\n\tp.mu.Unlock()\n\tif w == nil {\n\t\treturn fmt.Errorf(\"webview is not initialized\")\n\t}\n\n\tdone := make(chan error, 1)\n\tw.Dispatch(func() {\n\t\tdone <- fn(w)\n\t})\n\treturn <-done\n}\n\nfunc (p *pageWrapper) nativeCookies() ([]nativeCookieJSON, error) {\n\ttype cookieGetter interface {\n\t\tGetCookies(url string) ([]webview.Cookie, error)\n\t}\n\n\tvar cookies []webview.Cookie\n\terr := p.dispatch(func(w webview.WebView) error {\n\t\tgetter, ok := w.(cookieGetter)\n\t\tif !ok {","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/GopeedLab/gopeed/blob/7b7327ffb30816273a74b142cccc0bc10c5a4c67/internal/webview/goprovider/provider.go#L412-L448","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\npage := provider.NewPage(opts)\npage.Goto(url, gotoOpts) // \"webview is not initialized\" — start() not finished\n\n// after\npage, err := provider.NewPage(opts)\nif err != nil {\n    return err // includes startup timeout; page must not be used\n}\npage.Goto(url, gotoOpts)","handlingStrategy":"validation","validationCode":"// Only hand out a page after successful initialization\nvar (\n    pageCh = make(chan enginewebview.Page, 1)\n    errCh  = make(chan error, 1)\n)\n\nfunc openPage(opts enginewebview.BrowserOptions) (enginewebview.Page, error) {\n    select {\n    case p := <-pageCh:\n        return p, nil\n    case err := <-errCh:\n        return nil, err // includes startup timeout: never use the page afterwards\n    }\n}","typeGuard":null,"tryCatchPattern":"page, err := provider.NewPage(opts)\nif err != nil {\n    return err // do NOT proceed: p.view may be nil -> \"webview is not initialized\"\n}\nif err := page.Goto(url, gotoOpts); err != nil {\n    if strings.Contains(err.Error(), \"webview is not initialized\") {\n        return fmt.Errorf(\"page used before successful open: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["webview","initialization","lifecycle","race"],"backgroundTag":null,"analyzedSha":"7b7327ffb30816273a74b142cccc0bc10c5a4c67","analyzedAt":"2026-08-16T02:51:03.250Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}