grafana/k6 · error

clicking the checkbox did not change its state

Error message

clicking the checkbox did not change its state

What it means

check()/uncheck()/setChecked() click the checkbox and then re-read its 'checked' state (element_handle.go:1355-1377). If the click completed but the state did not flip to the requested value, k6 reports that the click had no effect: 'clicking the checkbox did not change its state'.

Source

Thrown at internal/js/modules/k6/browser/common/element_handle.go:1374

	state, err := h.checkElementState(apiCtx, "checked")
	if err != nil {
		return err
	}
	if checked == *state {
		return nil
	}

	err = h.click(p, NewMouseClickOptions())
	if err != nil {
		return err
	}

	state, err = h.checkElementState(apiCtx, "checked")
	if err != nil {
		return err
	}
	if checked != *state {
		return errors.New("clicking the checkbox did not change its state")
	}

	return nil
}

// Screenshot will instruct Chrome to save a screenshot of the current element and save it to specified file.
func (h *ElementHandle) Screenshot(
	opts *ElementHandleScreenshotOptions,
	sp ScreenshotPersister,
) ([]byte, error) {
	spanCtx, span := TraceAPICall(
		h.ctx,
		h.frame.page.targetID.String(),
		"elementHandle.screenshot",
	)
	defer span.End()

	span.SetAttributes(attribute.String("screenshot.path", opts.Path))

View on GitHub (pinned to 93accf6570)

Solutions

  1. Verify the selector resolves the actual input[type=checkbox] element, not its wrapper or label
  2. Ensure the input is enabled and not readonly before calling check()/uncheck()
  3. For framework-controlled widgets, click the real input directly or set the state via el.$eval('input', i => i.checked = true) followed by a change event
  4. Pass a position option to click the exact checkbox area when an overlay is present

Example fix

// before
const box = await page.$('.fancy-checkbox'); // div, not input
await box.check(); // click lands, state unchanged

// after
const box = await page.$('.fancy-checkbox input[type=checkbox]');
await box.check();
Defensive patterns

Strategy: retry

Validate before calling

// Verify the target is a real, enabled checkbox before checking
const ok = await el.evaluate(node =>
  node.tagName === 'INPUT' && node.type === 'checkbox' && !node.disabled && !node.readOnly
);
if (!ok) { /* fix the selector or use click/$eval instead */ }
await el.check();

Try / catch

try {
  await el.check();
} catch (e) {
  if (String(e.message).includes('did not change its state')) {
    await el.$eval('input', i => { i.checked = true; i.dispatchEvent(new Event('change', { bubbles: true })); });
  } else { throw e; }
}

Prevention

When it happens

Trigger: The selector targets a wrapper element (div/span with role=checkbox) instead of the real input; the input is disabled or readonly; an overlay or label intercepts the click; a controlled component (React/Vue) manages the checked property and reverts plain DOM clicks; the click toggles a different element than the one whose state is verified.

Common situations: Custom-designed checkboxes built from divs; React controlled inputs needing synthetic events; inputs disabled during form submission; animations or spinners covering the checkbox when clicked.

Related errors


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