grafana/k6 · error
double clicking on element
Error message
double clicking on element: %w
What it means
ElementHandle.dblClick() wraps the failure of the underlying pointer action. Before dispatching the two clicks through the CDP Input domain, the action scrolls the element into view and waits for it to be visible, enabled, stable, and able to receive the events; any of those waits timing out, or a CDP/session failure, is wrapped with the 'double clicking on element' prefix.
Solutions
- Wait for the element first: await el.waitFor({ state: 'visible' }) and check await el.isEnabled() before dblClick
- Pass a larger timeout: await el.dblClick({ timeout: '60s' })
- Skip actionability checks if the click is safe: await el.dblClick({ force: true })
- Dismiss blocking overlays (cookie banners, spinners) before the action
- Re-query the element handle right before clicking if the page re-renders frequently
Example fix
// before
const el = await page.$('#save');
await el.dblClick(); // times out: overlay covers the button
// after
const el = await page.$('#save');
await el.waitFor({ state: 'visible', timeout: '10s' });
await page.$('#cookie-ok').then(b => b && b.click()).catch(() => {});
await el.dblClick({ timeout: '30s' }); Defensive patterns
Strategy: try-catch
Validate before calling
// Make the element actionable before double clicking
await el.waitFor({ state: 'visible', timeout: '10s' });
if (!(await el.isEnabled())) {
throw new Error('element not enabled; cannot dblclick');
}
await el.dblClick({ timeout: '30s' }); Try / catch
try {
await el.dblClick({ timeout: '30s' });
} catch (e) {
const msg = String(e.message);
if (/timed out|timeout/i.test(msg)) {
await el.dblClick({ force: true }); // skip actionability on retry
} else if (/not attached|Could not find object/i.test(msg)) {
const fresh = await page.$(sel); // re-query and retry once
await fresh.dblClick({ timeout: '30s' });
} else throw e;
} Prevention
- Always waitFor({ state: 'visible' }) before pointer actions
- Dismiss known overlays (cookie banners, spinners) before clicking
- Set an explicit timeout per action instead of relying on the 30s default
- Use force:true only when you have already verified the element state yourself
When it happens
Trigger: Element is hidden, zero-sized, or display:none; an overlay covers it so the hit test fails ('other element would receive the event'); the element animates so it never reaches a stable position; the handle was detached by a re-render or navigation before the click landed; the timeout option or default (30s, K6_BROWSER_TIMEOUT) expires; the page or browser was closed mid-action.
Common situations: Cookie banners or modals covering the target button; CSS transitions keeping elements 'unstable'; React re-renders replacing the DOM node between query and click; slow CI machines where the default 30s timeout expires; headless-mode layout differences hiding elements.
Related errors
- hovering on element
- clickCount must be an integer, got
- clicking on element
- delay must be an integer, got
- filling element
AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18).
Data as JSON: /api/errors/fdcccff5a53dc454.
Report an issue: GitHub.
Appendix: source
Thrown at internal/js/modules/k6/browser/common/element_handle.go:880
return nil, fmt.Errorf("element is not an iframe")
}
frame, ok := h.frame.manager.getFrameByID(node.FrameID)
if !ok {
return nil, fmt.Errorf("frame not found for id %s", node.FrameID)
}
return frame, nil
}
// Dblclick scrolls element into view and double clicks on the element.
func (h *ElementHandle) Dblclick(opts *ElementHandleDblclickOptions) error {
dblclick := func(_ context.Context, handle *ElementHandle, p *Position) (any, error) {
return nil, handle.dblclick(p, opts.ToMouseClickOptions())
}
dblclickAction := h.newPointerAction(dblclick, &opts.ElementHandleBasePointerOptions)
if _, err := call(h.ctx, dblclickAction, opts.Timeout); err != nil {
return fmt.Errorf("double clicking on element: %w", err)
}
applySlowMo(h.ctx)
return nil
}
// DispatchEvent dispatches a DOM event to the element.
func (h *ElementHandle) DispatchEvent(typ string, eventInit any) error {
dispatchEvent := func(apiCtx context.Context, handle *ElementHandle) (any, error) {
return handle.dispatchEvent(apiCtx, typ, eventInit)
}
opts := NewElementHandleBaseOptions(h.DefaultTimeout())
dispatchEventAction := h.newAction(
[]string{}, dispatchEvent, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
)
if _, err := call(h.ctx, dispatchEventAction, opts.Timeout); err != nil {
return fmt.Errorf("dispatching element event %q: %w", typ, err)View on GitHub (pinned to 3fcf5388d7)