grafana/k6 · error

querying selector %q: %w

Error message

querying selector %q: %w

What it means

ElementHandle.Query() evaluated the injected querySelector script in the element's execution context and the evaluation itself failed (element_handle.go:1226). The wrapped error is a CDP/evaluation error: context destroyed by navigation, target crashed or closed, or the injected script could not run.

Source

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

			return nil, err
		}

		return frame.Query(afterFrameSelector, strict)
	}

	// No frame navigation - proceed with normal Query logic
	querySelector := `
		(node, injected, selector, strict) => {
			return injected.querySelector(selector, strict, node || document);
		}
	`
	opts := evalOptions{
		forceCallable: true,
		returnByValue: false,
	}
	result, err := h.evalWithScript(h.ctx, opts, querySelector, parsedSelector, strict)
	if err != nil {
		return nil, fmt.Errorf("querying selector %q: %w", selector, err)
	}
	if result == nil {
		return nil, nil //nolint:nilnil
	}
	handle, ok := result.(JSHandleAPI)
	if !ok {
		return nil, fmt.Errorf("querying selector %q, wrong type %T", selector, result)
	}
	element := handle.AsElement()
	if element == nil {
		defer func() {
			if err := handle.Dispose(); err != nil {
				err = fmt.Errorf("disposing element handle: %w", err)
				rerr = errors.Join(err, rerr)
			}
		}()
		return nil, fmt.Errorf("querying selector %q", selector)
	}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Await page.waitForLoadState() after any action that can navigate before querying
  2. Re-acquire the ElementHandle (its context died with the old document) and retry the query
  3. Wrap the call in try/catch with a single retry — these failures are usually transient races
  4. Check the browser/process logs if it correlates with resource exhaustion (target crash)

Example fix

// before
await page.click('a.details');
const row = await page.$('.row'); // context may be mid-navigation
// after
await page.click('a.details');
await page.waitForLoadState('domcontentloaded');
const row = await page.$('.row');
Defensive patterns

Strategy: try-catch

Validate before calling

// Stabilize before querying
await page.waitForLoadState('domcontentloaded');
if (!(await el.isVisible())) throw new Error('context likely navigated; re-query element');

Try / catch

try { return await el.$(sel); }
catch (e) {
  if (/querying selector/.test(e.message) && /context|target|navigation/i.test(e.message)) {
    await page.waitForLoadState(); return await el.$(sel); // single retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Page navigates or the iframe's context is destroyed between the call and evaluation; browser/tab closed mid-call; page crashes under load; the element's frame is cross-origin and being swapped.

Common situations: Querying immediately after a click that triggers an SPA route change; k6 tears the browser down while a query promise is pending; flaky under concurrency.

Related errors


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