grafana/k6 · error

checking element is hidden

Error message

checking element is hidden: %w

What it means

ElementHandle.isHidden() runs waitForElementState(['hidden']) with a zero timeout and deliberately ignores ErrTimedOut, returning a boolean for hidden/visible. A wrapped error is therefore a transport-level failure: the element handle is detached, the execution context was destroyed by navigation, or the session/frame is gone.

Solutions

  1. Use a live locator: await page.locator(sel).isHidden(), which re-resolves
  2. Check presence separately: const el = await page.$(sel); if (el === null) -> it is gone, not hidden
  3. Catch the error and treat it as 'no longer in DOM' when that matches the intent
  4. Re-acquire handles after any navigation or long wait

Example fix

// before
const el = await page.$('.toast');
await closeToast();
const hidden = await el.isHidden(); // throws: node removed from DOM

// after
await closeToast();
const gone = await page.$('.toast') === null;
const hidden = gone || await page.locator('.toast').isHidden();
Defensive patterns

Strategy: try-catch

Validate before calling

// Distinguish 'removed from DOM' from 'hidden' before checking
const gone = (await page.$('.toast')) === null;
const hidden = gone || (await page.locator('.toast').isHidden());

Try / catch

let hidden = true;
try {
  hidden = await el.isHidden();
} catch (e) {
  if (/not attached|Execution context|Could not find object/i.test(String(e.message))) {
    hidden = (await page.$(sel)) === null; // removed counts as hidden here
  } else throw e;
}

Prevention

When it happens

Trigger: The node was removed or replaced by a re-render before the check; the page navigated and the old context is gone; the element's frame was detached; the page was closed while the check ran.

Common situations: Asserting that toast/banner elements are hidden after SPAs remove them from the DOM entirely (removal is not 'hidden'); cached handles after route changes; teardown races at iteration end.

Related errors


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

Appendix: source

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

}

// 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) {
	ok, err := h.isHidden(h.ctx)
	// We don't care anout timeout errors here!
	if err != nil && !errors.Is(err, ErrTimedOut) {
		return false, fmt.Errorf("checking element is hidden: %w", err)
	}

	return ok, nil
}

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

	return ok, nil
}

// OwnerFrame returns the frame containing this element.
func (h *ElementHandle) OwnerFrame() (_ *Frame, rerr error) {

View on GitHub (pinned to 3fcf5388d7)