grafana/k6 · error
counting elements: %w
Error message
counting elements: %w
What it means
After the document handle is obtained, Frame.count() calls document.count(ctx, selector), which evaluates document.querySelectorAll(selector).length in the main world. This error wraps a failure of that evaluation — an invalid selector, a CDP error, or the execution context dying mid-evaluation.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:641
)
if _, err := call(f.ctx, act, opts.Timeout); err != nil {
return errorFromDOMError(err)
}
return nil
}
func (f *Frame) count(selector string) (int, error) {
f.log.Debugf("Frame:count", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
document, err := f.document()
if err != nil {
return 0, fmt.Errorf("getting document: %w", err)
}
c, err := document.count(f.ctx, selector)
if err != nil {
return 0, fmt.Errorf("counting elements: %w", err)
}
return c, nil
}
// Check clicks the first element found that matches selector.
func (f *Frame) Check(selector string, popts *FrameCheckOptions) error {
f.log.Debugf("Frame:Check", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
if err := f.check(selector, popts); err != nil {
return fmt.Errorf("checking %q: %w", selector, err)
}
applySlowMo(f.ctx)
return nil
}
View on GitHub (pinned to 93accf6570)
Solutions
- Validate the selector: try it in browser DevTools document.querySelectorAll('<sel>') or validate it before use.
- Wait for load state and retry once — transient context destruction during navigation resolves itself.
- Verify the page/browser is still open before calling (check earlier errors in the iteration).
Example fix
// before
const n = frame.count(`a[href=${dynamic}]`); // unquoted attr -> invalid selector
// after
const sel = `a[href="${dynamic}"]`;
const n = frame.count(sel); Defensive patterns
Strategy: try-catch
Validate before calling
const validSelector = (s) => { try { document.querySelectorAll(s); return true; } catch { return false; } }; // in-page via evaluate:
await frame.evaluate('(s) => { try { document.createDocumentFragment().querySelector(s); return true; } catch { return false; } }', sel); Try / catch
try {
const n = frame.count(sel);
} catch (e) {
console.warn(`count failed for ${sel}:`, e.message);
} Prevention
- Build selectors from constants, not string concatenation of raw input.
- Validate dynamic selectors once in DevTools before scripting them.
- Check the page is still open before querying after close-prone branches.
When it happens
Trigger: Malformed CSS selector (unbalanced brackets, stray parens) raises a DOMException in the page; the frame navigates between getting the document and evaluating count; the CDP session/target is closed (browser crashed or page closed).
Common situations: Dynamically-built selector strings (typos, missing quotes) passed to count(); counting during redirects; test continuing after the browser/page was closed by another branch; cross-origin iframes with a stale context.
Related errors
- getting document: %w
- evaluating JS in global context: %w
- getting viewport dimensions: %w
- WebSocket endpoint cannot be empty
- can't fetch the page for unknown reason
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/1e44d0a059147547.
Report an issue: GitHub.