grafana/k6 · error

checking element is editable

Error message

checking element is editable: %w

What it means

ElementHandle.isEditable() runs waitForElementState(['editable']) with a zero timeout and intentionally ignores ErrTimedOut. Any wrapped error is a hard failure from the injected state-check script or CDP: usually a detached element handle, a destroyed execution context (navigation), or a closed session.

Solutions

  1. Use a live query: await page.locator(sel).isEditable()
  2. Re-acquire the handle right before the check
  3. Catch the error and treat it as 'not editable / element gone' if that matches your test semantics
  4. Confirm the node still exists: await page.$(sel) returns null once removed

Example fix

// before
const el = await page.$('#email');
await stepThatReMountsTheForm();
const editable = await el.isEditable(); // throws: re-mounted

// after
await stepThatReMountsTheForm();
const editable = await page.locator('#email').isEditable();
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm existence, then check editability live
if ((await page.$(sel)) === null) throw new Error('field removed from DOM');
const editable = await page.locator(sel).isEditable();

Try / catch

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

Prevention

When it happens

Trigger: The input node was swapped out by a re-render before the check; the page navigated and destroyed the context; the element is inside a closed iframe; the browser session ended.

Common situations: Checking editability of fields in components that re-mount on validation errors; handles reused after route changes; checks racing page teardown at the end of an iteration.

Related errors


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

Appendix: source

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

}

// 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) {
	ok, err := h.isEnabled(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 enabled: %w", err)
	}

	return ok, nil
}

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

View on GitHub (pinned to 3fcf5388d7)