grafana/k6 · error
getting iframe frame: %w
Error message
getting iframe frame: %w
What it means
After locating the iframe element of a frame-crossing selector, stepIntoFrame calls ContentFrame(); this wraps its failure. The cause is either a CDP DOM.describeNode error ('getting remote node'), 'element is not an iframe', or 'frame not found for id ...'.
Source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:654
beforeFrame, afterFrame := h.splitSelectorAtFrame(parsedSelector, frameNavIndex)
// Find the iframe element using the "before frame" selector
iframeSelector := h.reconstructSelector(beforeFrame)
iframeHandle, err := h.waitForSelector(apiCtx, iframeSelector, opts)
if err != nil {
return nil, "", fmt.Errorf("finding iframe with selector %q: %w", iframeSelector, err)
}
// This is a valid response from waitForSelector. It means that the element
// was either hidden or detached.
if iframeHandle == nil {
return nil, "", ErrElementNotVisible
}
frame, err := iframeHandle.ContentFrame()
if err != nil {
return nil, "", fmt.Errorf("getting iframe frame: %w", err)
}
// Wait for selector in the iframe using the "after frame" selector
afterFrameSelector := h.reconstructSelector(afterFrame)
return frame, afterFrameSelector, nil
}
func (h *ElementHandle) waitForSelector(
apiCtx context.Context, selector string, opts *FrameWaitForSelectorOptions,
) (*ElementHandle, error) {
parsedSelector, err := NewSelector(selector)
if err != nil {
return nil, err
}
// Check for frame navigation in the selector
frameNavIndex := h.findFrameNavigationIndex(parsedSelector)View on GitHub (pinned to 93accf6570)
Solutions
- Tighten the iframe selector so it matches the <iframe> element itself
- Retry after the iframe content settles (wait for a known element inside it)
- Increase the timeout
- Use page.frameLocator() instead of hand-built frame-crossing selectors
Example fix
// before
await handle.waitForSelector('#container >> button'); // matched a div, not the iframe
// after
await handle.waitForSelector('#container iframe >> button'); Defensive patterns
Strategy: try-catch
Validate before calling
const isIframe = await handle.evaluate((el) => el.tagName === 'IFRAME');
if (!isIframe) throw new Error('selector must resolve to an iframe'); Try / catch
try {
await handle.waitForSelector('iframe >> .btn');
} catch (e) {
if (String(e).includes('getting iframe frame')) {
// matched node wasn't an iframe or it was swapped; tighten selector and retry
await handle.waitForSelector('#real-iframe >> .btn');
} else { throw e; }
} Prevention
- Aim the pre-frame selector at the <iframe> element itself
- Re-try after iframe src changes settle
When it happens
Trigger: A frame-crossing selector whose 'before frame' part matches an element that is not actually an iframe, or an iframe that navigated/detached between being matched and ContentFrame() being called.
Common situations: Selector matches a div wrapper that hosts the iframe; iframe src swapped (login redirects) during the query; iframe removed by a re-render mid-wait.
Related errors
- finding iframe with selector %q: %w
- getting remote node %q: %w
- waiting for selector %q: %w
- getting frame owner: %w
- updating extra HTTP headers: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/5105f8d807e70139.
Report an issue: GitHub.