grafana/k6 · error
parent frame has been detached
Error message
parent frame has been detached
What it means
Same getFrameElement flow (page.go:655-663): after walking to the root frame, k6 looks up the frame session for that root via p.getFrameSession. If no session is registered for the root frame id, the root's CDP session is gone (navigation swapped page sessions, or the target closed), so the DOM query for the frame owner cannot be executed.
Solutions
- Wait for the page to settle (waitForLoadState) before querying frame elements
- Re-acquire the page/frame objects after navigation and retry once
- If the popup/target may have closed, check page.isClosed() before the call
- Upgrade k6 — frame session lifecycle handling around navigation has seen fixes
Defensive patterns
Strategy: retry
Validate before calling
await page.waitForLoadState('load');
if (page.isClosed()) throw new Error('page closed before frame query');
const el = await frame.frameElement(); Try / catch
try {
await frame.frameElement();
} catch (e) {
if (/detached/.test(e.message)) {
await page.waitForLoadState('load');
return frame.frameElement(); // retry once after settle
}
throw e;
} Prevention
- Check page.isClosed() before frame queries on popups
- Do not run frame operations mid-navigation; wait for load state
- Upgrade k6 for session lifecycle fixes around navigation
When it happens
Trigger: frameElement() racing a top-level navigation that replaces the page session; the root target/page being closed while the call is in flight; an out-of-process iframe whose session has not been (re)attached.
Common situations: Same family as the other detach errors: navigation races, popup close races, CI slowness widening the window between frame tree walk and session use.
Related errors
- Error while parsing selector
- frame has been detached
- frame has been detached 1
- frame has been detached 2
- frame not found for id
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/a25f5fcb9ad3c899.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/page.go:664
if f == nil {
p.logger.Debugf("Page:getFrameElement", "sid:%v frame:nil", p.sessionID())
} else {
p.logger.Debugf("Page:getFrameElement", "sid:%v fid:%s furl:%s",
p.sessionID(), f.ID(), f.URL())
}
parent := f.parentFrame
if parent == nil {
return nil, errors.New("frame has been detached 1")
}
rootFrame := f
for ; rootFrame.parentFrame != nil; rootFrame = rootFrame.parentFrame {
}
parentSession, ok := p.getFrameSession(cdp.FrameID(rootFrame.ID()))
if !ok {
return nil, errors.New("parent frame has been detached")
}
action := dom.GetFrameOwner(cdp.FrameID(f.ID()))
backendNodeID, _, err := action.Do(cdp.WithExecutor(p.ctx, parentSession.session))
if err != nil {
if strings.Contains(err.Error(), "frame with the given id was not found") {
return nil, errors.New("frame has been detached")
}
return nil, fmt.Errorf("getting frame owner: %w", err)
}
parent = f.parentFrame
if parent == nil {
return nil, errors.New("frame has been detached 2")
}
return parent.adoptBackendNodeID(mainWorld, backendNodeID)
}
View on GitHub (pinned to 3fcf5388d7)