grafana/k6 · error
could not find frame with id %s
Error message
could not find frame with id %s
What it means
Frame.position looks up the frame for the page's target ID in the frame manager before computing coordinates (needed for pointer actions and offsets on frame content). If the manager no longer knows the target ID — the page is closing, the target crashed, or the frame tree was rebuilt mid-action — the lookup fails with this error. It is a lifecycle race, not a selector problem.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:376
f.loadingStartedTime = time.Now()
}
func (f *Frame) onLoadingStopped() {
f.log.Debugf("Frame:onLoadingStopped", "fid:%s furl:%q", f.ID(), f.URL())
// TODO: We should start a timer here and allow the user
// to set how long to wait until after onLoadingStopped
// has occurred. The reason we may want a timeout here
// are for websites where they perform many network
// requests so it may take a long time for us to see
// a networkIdle event or we may never see one if the
// website never stops performing network requests.
}
func (f *Frame) position() (*Position, error) {
frame, ok := f.manager.getFrameByID(cdp.FrameID(f.page.targetID))
if !ok {
return nil, fmt.Errorf("could not find frame with id %s", f.page.targetID)
}
if frame == f.page.frameManager.MainFrame() {
return &Position{X: 0, Y: 0}, nil
}
element, err := frame.FrameElement()
if err != nil {
return nil, err
}
box, err := element.BoundingBox()
if err != nil {
return nil, fmt.Errorf("finding position in frame: %w", err)
}
return &Position{X: box.X, Y: box.Y}, nil
}
func (f *Frame) removeChildFrame(child *Frame) {View on GitHub (pinned to 93accf6570)
Solutions
- Ensure no in-flight actions when closing a page; await actions before page.close()
- Retry the action after verifying the page is still open
- If renderers crash repeatedly (OOM), reduce page weight or increase resources
Example fix
// before await page.close(); await el.click(); // position lookup on a closing page // after await el.click(); await page.close();
Defensive patterns
Strategy: validation
Validate before calling
if (page.isClosed()) throw new Error('page already closed');
await el.click(); Try / catch
try {
await el.click();
} catch (e) {
if (/could not find frame with id/.test(e.message)) {
// page/target is gone: skip or restart the scenario
} else throw e;
} Prevention
- Await all actions before closing pages
- Sequence close() after action promises settle
- Guard action entry points with page.isClosed()
When it happens
Trigger: Pointer/click actions (which need frame position for coordinate math) racing page.close() or a target crash; navigations rebuilding the frame tree while a click is in flight; actions on a page whose renderer process died.
Common situations: Cleanup paths where an action is still queued when the iteration ends; high load crashing renderers; closing pages from another async branch while actions run.
Related errors
- getting document element: nil document
- waitFor retry threshold reached
- parent frame has been detached
- frame has been detached 2
- attaching new page: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/9e86ca93c2638319.
Report an issue: GitHub.