grafana/k6 · error
the page may have navigated away or the element is now mi
Error message
the page may have navigated away or the element is now missing. It might happen when k6 and/or Chrome are overloaded. You might need to increase the compute resources
What it means
DOM.resolveNode succeeded but returned no remote object. The code comment states the cause: a race condition between k6 trying to act on an element and Chrome moving on (typically navigating). k6 treats a nil remote object as 'the node disappeared under us' and returns this advisory message, which also notes that k6 and/or Chrome being overloaded can trigger it.
Source
Thrown at internal/js/modules/k6/browser/common/execution_context.go:111
e.sid, e.stid, e.fid, e.id, e.furl, backendNodeID)
var (
remoteObj *runtime.RemoteObject
err error
)
action := dom.ResolveNode().
WithBackendNodeID(backendNodeID).
WithExecutionContextID(e.id)
if remoteObj, err = action.Do(cdp.WithExecutor(e.ctx, e.session)); err != nil {
return nil, fmt.Errorf("resolving DOM node: %w", err)
}
// This can occur due to race conditions between trying to click on an element
// and chrome moving on (e.g. navigating).
if remoteObj == nil {
return nil, fmt.Errorf(`the page may have navigated away or the element is
now missing. It might happen when k6 and/or Chrome are overloaded. You
might need to increase the compute resources`)
}
return NewJSHandle(e.ctx, e.session, e, e.frame, remoteObj, e.logger).AsElement(), nil
}
// Adopts the specified element handle into this execution context from another execution context.
func (e *ExecutionContext) adoptElementHandle(eh *ElementHandle) (*ElementHandle, error) {
var (
efid cdp.FrameID
esid target.SessionID
)
if eh.frame != nil {
efid = cdp.FrameID(eh.frame.ID())
}
if eh.session != nil {
esid = eh.session.ID()View on GitHub (pinned to 93accf6570)
Solutions
- Retry the action: re-query the element and act again — the race is transient
- Await the expected navigation (waitForNavigation / waitForLoadState) before further actions
- Increase compute for Chrome (more CPU, fewer VUs per browser) if it appears intermittently under load
- Let the DOM settle after dynamic updates before interacting
Example fix
// before
const el = await page.$('#link');
await el.click();
await el.click(); // second click races the navigation
// after
const el = await page.$('#link');
await Promise.all([page.waitForNavigation(), el.click()]);
const el2 = await page.$('#next');
await el2.click(); Defensive patterns
Strategy: retry
Try / catch
try {
await el.click();
} catch (e) {
if (/navigated away|now missing/.test(e.message)) {
await page.waitForLoadState();
el = await page.$('#link');
await el.click();
} else throw e;
} Prevention
- Pair navigation-triggering actions with waitForNavigation
- Re-query elements after any navigation
- Provision enough CPU/memory for Chrome under load
- Avoid acting on the same handle twice across a navigation boundary
When it happens
Trigger: Page navigates between the moment k6 resolves the element's backend node and the moment it materializes an object; the node is removed by a SPA re-render; Chrome is resource-starved and drops the node; the tab closes during the action.
Common situations: High-VU runs where a single Chrome instance is CPU/memory bound; slow machines or constrained CI containers running the browser; clicking elements that trigger immediate navigation (form submits, links); lazy loading replacing DOM subtrees.
Related errors
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/e2a3385aff8bc560.
Report an issue: GitHub.