grafana/k6 · error

checking element is disabled

Error message

checking element is disabled: %w

What it means

ElementHandle.isDisabled() runs waitForElementState(['disabled']) with a zero timeout and ignores ErrTimedOut by design. The wrapped error therefore comes from the injected script or CDP layer: a detached element handle, an execution context destroyed by navigation, or a closed session - not from the element simply being enabled.

Solutions

  1. Re-acquire the element or use page.locator(sel).isDisabled() which re-resolves the node
  2. Treat thrown errors as 'element gone' via try/catch when the check is advisory
  3. Verify attachment first: await el.evaluate(e => e.isConnected)
  4. Do not store handles across page.goto() or long async flows

Example fix

// before
const el = await page.$('#submit');
await flowThatReplacesTheButton();
const disabled = await el.isDisabled(); // throws: node replaced

// after
await flowThatReplacesTheButton();
const disabled = await page.locator('#submit').isDisabled();
Defensive patterns

Strategy: try-catch

Validate before calling

// Re-resolve state with a live query
const disabled = (await page.$(sel)) === null
  ? true // gone implies not interactable in most test semantics
  : await page.locator(sel).isDisabled();

Try / catch

let disabled = false;
try {
  disabled = await el.isDisabled();
} catch (e) {
  if (/not attached|Execution context|Could not find object/i.test(String(e.message))) {
    disabled = await page.locator(sel).isDisabled();
  } else throw e;
}

Prevention

When it happens

Trigger: The element node was replaced by a re-render after the handle was acquired; navigation destroyed the execution context; the frame or page containing the element closed; the CDP session stalled.

Common situations: Forms whose controls are recreated during multi-step wizards; SPAs re-rendering disabled/enabled buttons on state changes; handles cached from earlier screens.

Related errors


AI-assisted analysis of grafana/k6@3fcf5388d7 (2026-08-18). Data as JSON: /api/errors/38cf16c8fbc11105. Report an issue: GitHub.

Appendix: source

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

}

// IsChecked checks if a checkbox or radio is checked.
func (h *ElementHandle) IsChecked() (bool, error) {
	ok, err := h.isChecked(h.ctx, 0)
	// We don't care about timeout errors here!
	if err != nil && !errors.Is(err, ErrTimedOut) {
		return false, fmt.Errorf("checking element is checked: %w", err)
	}

	return ok, nil
}

// IsDisabled checks if the element is disabled.
func (h *ElementHandle) IsDisabled() (bool, error) {
	ok, err := h.isDisabled(h.ctx, 0)
	// We don't care anout timeout errors here!
	if err != nil && !errors.Is(err, ErrTimedOut) {
		return false, fmt.Errorf("checking element is disabled: %w", err)
	}

	return ok, nil
}

// IsEditable checks if the element is editable.
func (h *ElementHandle) IsEditable() (bool, error) {
	ok, err := h.isEditable(h.ctx, 0)
	// We don't care anout timeout errors here!
	if err != nil && !errors.Is(err, ErrTimedOut) {
		return false, fmt.Errorf("checking element is editable: %w", err)
	}

	return ok, nil
}

// IsEnabled checks if the element is enabled.
func (h *ElementHandle) IsEnabled() (bool, error) {

View on GitHub (pinned to 3fcf5388d7)