grafana/k6 · error
calling function: %w
Error message
calling function: %w
What it means
Thrown by Frame.runActionOnSelector when the query succeeded and a handle was found, but the element action itself (fn(ctx, handle) — the click/type/focus implementation) returned an error. The wrapped error typically comes from CDP: element not visible, not stable, detached during action, or the browser refused the input (for example intercepted by an overlay).
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:2369
// id returns the CDP runtime ID of this execution context.
ID() runtime.ExecutionContextID
}
func (f *Frame) runActionOnSelector(
ctx context.Context, selector string, strict bool, fn elementHandleActionFunc, nullResponder func() bool,
) (bool, error) {
handle, err := f.Query(selector, strict)
if err != nil {
return false, fmt.Errorf("query: %w", err)
}
if handle == nil {
f.log.Debugf("Frame:runActionOnSelector:nilHandler", "fid:%s furl:%q selector:%s", f.ID(), f.URL(), selector)
return nullResponder(), err
}
v, err := fn(ctx, handle)
if err != nil {
return false, fmt.Errorf("calling function: %w", err)
}
bv, ok := v.(bool)
if !ok {
return false, fmt.Errorf("unexpected type %T", v)
}
return bv, nil
}
//nolint:unparam
func (f *Frame) newAction(
selector string, state DOMElementState, strict bool, fn elementHandleActionFunc, states []string,
force bool, retry bool, noWaitAfter bool, timeout time.Duration,
) func(apiCtx context.Context, resultCh chan any, errCh chan error) {
// We execute a frame action in the following steps:
// 1. Find element matching specified selector
// 2. Wait for it to reach specified DOM stateView on GitHub (pinned to 93accf6570)
Solutions
- Wait for the element to be actionable: page.waitForSelector(sel, { state: 'visible' }) before the action
- Retry the action — transient detach during SPA rerender usually succeeds on a second attempt with a fresh selector call
- If an overlay legitimately intercepts, use { force: true } to bypass actionability checks
- Stabilize the app under test (disable animations) rather than fighting the checks
Example fix
// before
await page.click('#save'); // hidden behind a cookie banner
// after
await page.waitForSelector('#save', { state: 'visible' });
await page.click('#save', { timeout: 30_000 });
// or bypass overlays when intentional: page.click('#save', { force: true }) Defensive patterns
Strategy: retry
Type guard
function isActionFailure(e) {
return e instanceof Error && /calling function/.test(e.message);
} Try / catch
async function clickStable(page, sel, tries = 3) {
for (let i = 0; i < tries; i++) {
try {
await page.waitForSelector(sel, { state: 'visible' });
return await page.click(sel);
} catch (e) { if (i === tries - 1) throw e; }
}
} Prevention
- Wait for visible state before interacting
- Retry once on transient detach from SPA rerenders
- Use force only when overlay interception is intentional
When it happens
Trigger: page.click(sel) on an element with zero size or display:none; element re-rendered (detached) between query and action; overlay/toaster intercepting the pointer; page navigating mid-click; actionability checks failing because the element keeps moving.
Common situations: Animated buttons (hover effects, sticky headers); SPAs that re-render on every state change invalidating handles; CI headless environments where layout differs; clicking before fonts/layout settle.
Related errors
- clicking on element: %w
- clicking on %q: %w
- parsing element click options: %w
- parsing click options: %w
- finding clickable point: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/44c218fad361c18a.
Report an issue: GitHub.