grafana/k6 · error
frame has been detached 1
Error message
frame has been detached 1
What it means
Page.getFrameElement (page.go:643-653) resolves the <iframe>/<frame> DOM element that owns a frame (used by frame.frameElement()). It first needs the frame's parent; if parentFrame == nil the frame either is the main frame or has been detached, so there is no parent in which to look for the frame element.
Solutions
- Never call frameElement() on the main frame — it has no owner element by definition
- Re-fetch frames from page.frames() after each navigation and use those fresh references
- Before calling, confirm the frame is still live (its id still appears in page.frames())
- Wrap in try-catch and re-acquire the frame on failure; a detached frame never comes back
Example fix
// before
const el = await page.frames()[0].frameElement(); // may be detached
// after
const frames = page.frames();
const live = frames.find(f => f.name() === 'chart');
if (live) { const el = await live.frameElement(); } Defensive patterns
Strategy: validation
Validate before calling
// Skip the main frame and confirm the frame is still listed
const f = page.frames().find(fr => fr.name() === 'widget');
if (f) {
const el = await f.frameElement();
} else {
// frame gone — re-acquire or skip
} Try / catch
try {
handle = await frame.frameElement();
} catch (e) {
if (/detached/.test(e.message)) {
const fresh = page.frames().find(fr => fr.name() === 'widget');
handle = fresh ? await fresh.frameElement() : null;
} else throw e;
} Prevention
- Never call frameElement() on the main frame
- Re-fetch frames from page.frames() after every navigation
- Treat 'frame has been detached' as 're-acquire the frame' in all handlers
When it happens
Trigger: Calling page.mainFrame().frameElement() (main frame has no parent); calling frameElement() on an iframe frame that was removed from the DOM by navigation or script while you still held the reference.
Common situations: Iterating page.frames() while navigation adds/removes iframes; holding frame references across page.goto; ad or embed iframes deleted by their own scripts.
Related errors
- frame has been detached
- frame has been detached 2
- Error while parsing selector
- frame not found for id
- parent frame has been detached
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/e2840528bc764522.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/page.go:655
_, err := action.Do(cdp.WithExecutor(p.ctx, p.session))
if err != nil {
return fmt.Errorf("evaluating script on document: %w", err)
}
return nil
}
func (p *Page) getFrameElement(f *Frame) (handle *ElementHandle, _ error) {
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)View on GitHub (pinned to 3fcf5388d7)