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

  1. Validate the selector: try it in browser DevTools document.querySelectorAll('<sel>') or validate it before use.
  2. Wait for load state and retry once — transient context destruction during navigation resolves itself.
  3. 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

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


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/1e44d0a059147547. Report an issue: GitHub.