grafana/k6 · error
no frame found for id %s
Error message
no frame found for id %s
What it means
OwnerFrame() found a FrameID on the node, but the browser's FrameManager has no frame registered with that ID (element_handle.go:1164). The frame was detached or destroyed between the DOM.describeNode call and the manager lookup, or the frame was never tracked (out-of-process iframe crash).
Source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:1164
}
}()
if documentHandle.remoteObject.ObjectID == "" {
return nil, err
}
var node *cdp.Node
action := dom.DescribeNode().WithObjectID(documentHandle.remoteObject.ObjectID)
if node, err = action.Do(cdp.WithExecutor(h.ctx, h.session)); err != nil {
return nil, fmt.Errorf("getting node in frame: %w", err)
}
if node == nil || node.FrameID == "" {
return nil, fmt.Errorf("no frame found for node: %w", err)
}
frame, ok := h.frame.manager.getFrameByID(node.FrameID)
if !ok {
return nil, fmt.Errorf("no frame found for id %s", node.FrameID)
}
return frame, nil
}
// Press scrolls element into view and presses the given keys.
func (h *ElementHandle) Press(key string, opts *ElementHandlePressOptions) error {
press := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return nil, handle.press(apiCtx, key, KeyboardOptions{})
}
pressAction := h.newAction(
[]string{}, press, false, withRetry, opts.NoWaitAfter, opts.Timeout,
)
if _, err := call(h.ctx, pressAction, opts.Timeout); err != nil {
return fmt.Errorf("pressing %q on element: %w", key, err)
}
applySlowMo(h.ctx)View on GitHub (pinned to 93accf6570)
Solutions
- Wait for the frame/element explicitly before acting: page.waitForSelector inside the frame, or frameLocator with an explicit timeout
- Retry the whole query once after a short wait — frame detachment is usually transient if the frame is re-created
- Assert the iframe still exists (page.frames() / frame url check) before dereferencing elements inside it
- If the iframe is legitimately optional, guard the interaction with a existence check
Example fix
// before
const btn = page.locator('iframe#ad >> button');
btn.click(); // iframe removed mid-resolution -> no frame found for id ...
// after
const frame = page.frames().find(f => f.url().includes('/widget'));
if (frame) { await frame.click('button'); } Defensive patterns
Strategy: retry
Validate before calling
// Ensure the frame still exists before interacting inside it
const frame = page.frames().find(f => f.url().includes('/app/iframe'));
if (!frame) { /* skip or wait */ } Try / catch
try { await frameEl.click(); }
catch (e) { if (/no frame found for id/.test(e.message)) { await page.waitForTimeout(500); await page.waitForLoadState(); /* retry once */ } else throw e; } Prevention
- Check page.frames() before dereferencing iframe content
- Expect iframe teardown in dynamic pages and code the skip path
- Wait for elements inside the frame, not just the iframe tag
When it happens
Trigger: An iframe is removed from the DOM (ads, popups, lazy unmount) right as you interact with an element inside it; frame tree replaced by navigation; OOP iframe process crash.
Common situations: Scripts that drill into iframes that get torn down dynamically; SPAs that re-render iframe containers; flaky only when the frame lifecycle races the action.
Related errors
- getting document element: nil document
- waitFor retry threshold reached
- frame has been detached 1
- parent frame has been detached
- frame has been detached
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/1fc531bb749b9c88.
Report an issue: GitHub.