projectdiscovery/katana · error
could not initialize javascript env
Error message
could not initialize javascript env
What it means
createBrowserPageFunc wraps js.InitJavascriptEnv(page) failure with this message. InitJavascriptEnv sets up katana's in-page JavaScript execution environment (helpers exposed to page scripts / hooking) by evaluating setup code in the page. Failure means the CDP evaluation against the page failed — typically because the page's CDP session or browser connection is no longer valid.
Source
Thrown at pkg/engine/headless/browser/browser.go:467
browserPage := &BrowserPage{
Page: page,
Browser: browser,
launcher: l,
cancel: cancel,
userDataDir: tempDir,
}
if err := browserPage.handlePageDialogBoxes(); err != nil {
return nil, err
}
// Add stealth evasion JS
_, err = page.EvalOnNewDocument(stealth.JS)
if err != nil {
return nil, errors.Wrap(err, "could not initialize stealth")
}
err = js.InitJavascriptEnv(page)
if err != nil {
return nil, errors.Wrap(err, "could not initialize javascript env")
}
// Success - cancel any deferred cleanup
successfulPageCreation = true
return browserPage, nil
}
// GetPageFromPool returns a page from the pool
func (l *Launcher) GetPageFromPool() (*BrowserPage, error) {
browserPage, err := l.browserPool.Get(l.createBrowserPageFunc)
if err != nil {
return nil, err
}
// TODO: should we check if the browser is alive because sometimes it
// might die?
return browserPage, nil
}
View on GitHub (pinned to e3e742739c)
Solutions
- Read the wrapped error: 'Execution context was destroyed' means the page navigated during setup — retry page creation; 'target closed' means the browser died — relaunch it.
- Ensure the page context/cancelCtx is not already cancelled before initialization (check page.GetContext().Err()).
- Retry the whole createBrowserPageFunc call rather than individual steps, since a partially initialized page is discarded by its deferred cleanup.
- Update katana/rod if the JS env initialization conflicts with the current Chrome protocol version.
Example fix
// before: ignoring context state before init
if err := js.InitJavascriptEnv(page); err != nil { return nil, err }
// after: bail out early on a dead context and recreate
if err := page.GetContext().Err(); err != nil {
return nil, fmt.Errorf("page context dead, recreating: %w", err)
}
if err := js.InitJavascriptEnv(page); err != nil {
return recreateBrowserPage()
} Defensive patterns
Strategy: retry
Validate before calling
if err := page.GetContext().Err(); err != nil {
return fmt.Errorf("page context cancelled before js env init: %w", err)
} Try / catch
if err := js.InitJavascriptEnv(page); err != nil {
if strings.Contains(err.Error(), "context canceled") || strings.Contains(err.Error(), "target closed") {
return recreateBrowserPage() // retry full page creation once
}
return err
} Prevention
- Ensure crawl deadlines exceed page-setup time so cancelCtx isn't fired during init.
- Recreate whole pages rather than re-running individual init steps.
- Watch for rapid navigation during setup; consider waiting for load before init.
- Keep protocol definitions in sync with the installed Chrome version.
When it happens
Trigger: js.InitJavascriptEnv(page) returning an error when its internal page.Eval/Evaluate calls fail due to a closed target, cancelled context (e.g. the cancelCtx created at browser.go:446 was already cancelled), browser crash, or an invalid/unresponsive execution context.
Common situations: Pages whose context was cancelled because an enclosing crawl deadline expired during setup; Chrome crash under memory pressure between stealth init and JS env init; navigation racing with setup invalidating the execution context ('Execution context was destroyed' errors); remote browser disconnects.
Related errors
- could not create new page
- could not initialize stealth
- could not enable fetch domain
- failed to inject utils.js
- failed to inject page-init.js
AI-assisted analysis of projectdiscovery/katana@e3e742739c (2026-09-03).
Data as JSON: /api/errors/47d3129d7f0b7b9b.
Report an issue: GitHub.