grafana/k6 · error

getting injected script

Error message

getting injected script: %w

What it means

Internal error in the k6 browser module whenever an ElementHandle runs an injected-script evaluation (behind check, fill, selectOption, setInputFiles, hover, etc.). getInjectedScript evaluates the bundled helper-script source once per ExecutionContext and caches it; failure here means that bootstrap evaluation failed — classically because the execution context was destroyed by navigation, or CDP rejected the evaluation.

Solutions

  1. Gate actions on load state: await page.waitForLoadState('domcontentloaded') or waitForNavigation after clicks that redirect, before further element actions.
  2. Re-acquire page/frame/handle after any navigation — never reuse handles across pages.
  3. Ensure the k6 test iteration does not exit while browser promises are pending (await all async operations or close pages deliberately).
  4. If the renderer is crashing, reduce concurrency or check the page for memory-heavy behavior; run with DEBUG to see the underlying CDP error.

Example fix

// before
await page.click('#logout'); // triggers navigation
const el = await page.$('#login');
await el.fill('user'); // context destroyed -> injected script bootstrap fails

// after
await Promise.all([page.waitForNavigation(), page.click('#logout')]);
const el = await page.waitForSelector('#login', { state: 'visible' });
await el.fill('user');
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForLoadState('domcontentloaded');
// re-acquire handle from a live frame before any action that uses the injected script
const el = await page.waitForSelector(sel, { state: 'attached' });
await el.fill('value');

Try / catch

for (let i = 0; i < 2; i++) {
  try { await action(el); break; }
  catch (e) {
    if (i === 1 || !String(e).includes('injected script')) throw e;
    await page.waitForLoadState('domcontentloaded');
    el = await page.waitForSelector(sel, { state: 'attached' });
  }
}

Prevention

When it happens

Trigger: Any element action on a handle whose frame navigated (context destroyed) or was closed; evaluating while the page is being torn down at test end; a crash of the renderer process invalidating contexts. Because every action (click state checks, fill, select) calls evalWithScript, this error can surface wrapped inside many higher-level action failures.

Common situations: Actions issued against a page mid-navigation (click triggers redirect, then a state check runs on the dead context); test iteration ending while async browser actions are still in flight; renderer OOM/crash under memory pressure in large tests.

Related errors


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

Appendix: source

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

// WaitForSelector waits for the selector to appear in the DOM.
func (h *ElementHandle) WaitForSelector(selector string, opts *FrameWaitForSelectorOptions) (*ElementHandle, error) {
	handle, err := h.waitForSelector(h.ctx, selector, opts)
	if err != nil {
		return nil, fmt.Errorf("waiting for selector %q: %w", selector, err)
	}

	return handle, nil
}

// evalWithScript evaluates the given js code in the scope of this ElementHandle and returns the result.
// The js code can call helper functions from injected_script.js.
func (h *ElementHandle) evalWithScript(
	ctx context.Context,
	opts evalOptions, js string, args ...any,
) (any, error) {
	script, err := h.execCtx.getInjectedScript(h.ctx)
	if err != nil {
		return nil, fmt.Errorf("getting injected script: %w", err)
	}
	return h.eval(ctx, opts, js, append([]any{script}, args...)...)
}

// eval evaluates the given js code in the scope of this ElementHandle and returns the result.
func (h *ElementHandle) eval(
	ctx context.Context,
	opts evalOptions, js string, args ...any,
) (any, error) {
	// passing `h` makes it evaluate js code in the element handle's scope.
	return h.execCtx.eval(ctx, opts, js, append([]any{h}, args...)...)
}

func (h *ElementHandle) newAction(
	states []string, fn elementHandleActionFunc, force bool, retry bool, noWaitAfter bool, timeout time.Duration,
) func(apiCtx context.Context, resultCh chan any, errCh chan error) {
	// All or a subset of the following actionability checks are made before performing the actual action:
	// 1. Attached to DOM

View on GitHub (pinned to 3fcf5388d7)