grafana/k6 · error

unchecking %q: %w

Error message

unchecking %q: %w

What it means

Frame.Uncheck() delegates to setChecked(..., false) inside a pointer action with waits. This error wraps any failure of that pipeline — wait timeout, wrong element kind ('not a checkbox or radio button'), or element not connected at the moment of the operation.

Source

Thrown at internal/js/modules/k6/browser/common/frame.go:706

// SetChecked sets the checked state of the first element found that matches the selector.
func (f *Frame) SetChecked(selector string, checked bool, popts *FrameCheckOptions) error {
	f.log.Debugf("Frame:SetChecked", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)

	if err := f.setChecked(selector, checked, popts); err != nil {
		return fmt.Errorf("setting checked %q: %w", selector, err)
	}

	applySlowMo(f.ctx)

	return nil
}

// Uncheck the first found element that matches the selector.
func (f *Frame) Uncheck(selector string, popts *FrameUncheckOptions) error {
	f.log.Debugf("Frame:Uncheck", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)

	if err := f.uncheck(selector, popts); err != nil {
		return fmt.Errorf("unchecking %q: %w", selector, err)
	}

	applySlowMo(f.ctx)

	return nil
}

func (f *Frame) uncheck(selector string, opts *FrameUncheckOptions) error {
	uncheck := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {
		return nil, handle.setChecked(apiCtx, false, p)
	}
	act := f.newPointerAction(
		selector, DOMElementStateAttached, opts.Strict, uncheck, &opts.ElementHandleBasePointerOptions,
	)
	if _, err := call(f.ctx, act, opts.Timeout); err != nil {
		return errorFromDOMError(err)
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use a unique selector for the specific checkbox (data-testid).
  2. Dismiss overlays and waitForSelector visible before unchecking.
  3. Bump the timeout option if rendering is slow.

Example fix

// before
frame.uncheck('.consent'); // matches many boxes -> strict failure

// after
await frame.waitForSelector('input.consent[data-testid=ads]', { state: 'visible' });
frame.uncheck('input.consent[data-testid=ads]');
Defensive patterns

Strategy: validation

Validate before calling

await frame.waitForSelector(sel, { state: 'visible', timeout: 30000 });
const kind = await frame.evaluate('(s) => document.querySelector(s)?.type', sel);
if (kind !== 'checkbox' && kind !== 'radio') throw new Error(`${sel} is ${kind}, not checkable`);

Try / catch

try {
  frame.uncheck(sel);
} catch (e) {
  console.warn(`uncheck(${sel}) failed:`, e.message);
}

Prevention

When it happens

Trigger: Unchecking a selector that matches no checkbox/radio, a hidden or overlapped checkbox, multiple strict-mode matches, or an element detached by re-render between the wait and the action.

Common situations: Unchecking pre-checked consent boxes behind cookie banners; list rows with many same-named checkboxes; SPA re-mounts the input during unchecked state.

Related errors


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