{"record":{"id":"8bfe16c10c52059e","repo":"GopeedLab/gopeed","slug":"webview-startup-timeout","errorCode":null,"errorMessage":"webview startup timeout","messagePattern":"webview startup timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/webview/goprovider/provider.go","lineNumber":147,"sourceCode":"\n\t\tapplyWindowOptions(w, p.opts)\n\t\tw.SetHtml(buildBootstrapHTML(p.callbackName, p.readyID))\n\t\tw.Run()\n\t\tw.Destroy()\n\t\tclose(p.done)\n\t}\n\n\tif !postMainThreadTask(run) {\n\t\tgo run()\n\t}\n\n\tselect {\n\tcase err := <-p.ready:\n\t\tp.tracef(\"open %dms\", time.Since(startedAt).Milliseconds())\n\t\treturn err\n\tcase <-time.After(10 * time.Second):\n\t\tp.tracef(\"open timeout %dms\", time.Since(startedAt).Milliseconds())\n\t\treturn fmt.Errorf(\"webview startup timeout\")\n\t}\n}\n\nfunc (p *pageWrapper) AddInitScript(script string) error {\n\treturn p.dispatch(func(w webview.WebView) error {\n\t\tw.Init(script)\n\t\treturn nil\n\t})\n}\n\nfunc (p *pageWrapper) Goto(url string, opts enginewebview.GotoOptions) error {\n\tstartedAt := time.Now()\n\tp.drainLoads()\n\tif err := p.dispatch(func(w webview.WebView) error {\n\t\tp.mu.Lock()\n\t\tp.url = url\n\t\tp.mu.Unlock()\n\t\tw.Navigate(url)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/GopeedLab/gopeed/blob/7b7327ffb30816273a74b142cccc0bc10c5a4c67/internal/webview/goprovider/provider.go#L129-L165","documentation":"pageWrapper.start() spawns the native webview (webview.New or NewHeadless), binds the callback, sets bootstrap HTML, then waits on the ready channel with a hard 10-second budget. If the runtime never signals ready within that window, this error returns and the page is unusable. The tracef call just before it records how many ms actually elapsed.","triggerScenarios":"Running a visible webview where no GUI session exists (no DISPLAY / Wayland session, e.g. plain SSH or a container) without Headless set; missing WebView2 runtime on Windows or WebKitGTK shared libraries on Linux; the main-thread task queue blocked by another long-running window; extremely slow cold start under heavy load.","commonSituations":"CI pipelines or servers invoking webview-dependent features without headless mode; minimal Docker images lacking libwebkit2gtk; first launch after an OS update while the webview runtime rebuilds its cache; multiple providers competing for the one UI thread.","solutions":["Set the Headless option when there is no display (start() then uses webview.NewHeadless)","On Linux install WebKitGTK dev/runtime packages; on Windows confirm the WebView2 runtime is installed","Ensure DISPLAY/WAYLAND_DISPLAY are set in remote sessions, or forward X","Check the provider trace logs (title containing the debug marker) to see whether open hung at 0ms or crept to 10000ms — a 0ms hang points at a blocked task queue, a near-10000ms value at slow init"],"exampleFix":"// before\npage, err := provider.NewPage(enginewebview.BrowserOptions{}) // in CI: no display -> startup timeout\n\n// after\npage, err := provider.NewPage(enginewebview.BrowserOptions{Headless: true}) // headless init path","handlingStrategy":"retry","validationCode":"// Check the environment before opening a webview\nfunc canOpenGUI() bool {\n    if os.Getenv(\"Headless\") != \"\" { /* app-level headless flag */ }\n    return os.Getenv(\"DISPLAY\") != \"\" || os.Getenv(\"WAYLAND_DISPLAY\") != \"\" || runtime.GOOS == \"windows\" || runtime.GOOS == \"darwin\"\n}","typeGuard":null,"tryCatchPattern":"page, err := provider.NewPage(opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"webview startup timeout\") {\n        // one cold-start retry, then abort the session; do not loop on a broken environment\n        page, err = provider.NewPage(opts)\n        if err != nil {\n            return fmt.Errorf(\"webview unavailable in this environment: %w\", err)\n        }\n    } else {\n        return err\n    }\n}","preventionTips":["Set Headless in CI/containers; require a display for windowed mode","Pre-install the webview runtime (WebView2 on Windows, WebKitGTK on Linux)","Keep the main thread free of other blocking work while a webview boots"],"tags":["webview","startup","timeout","environment","gui"],"backgroundTag":null,"analyzedSha":"7b7327ffb30816273a74b142cccc0bc10c5a4c67","analyzedAt":"2026-08-16T02:51:03.250Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}