grafana/k6 · error

getProperties

Error message

getProperties: %w

What it means

In k6 browser's frame.selectOption, after selecting, the code calls getProperties() on the <select> element's JSHandle via CDP Runtime.getProperties to enumerate the chosen <option> values. This error means that CDP call failed, typically because the execution context or session died between selection and property read.

Solutions

  1. If the select navigates on change, expect it: wait for the navigation, then verify state instead of relying on the return value
  2. Retry selectOption once after the new document loads
  3. Prevent auto-submit in the test environment so the context survives the property read
  4. Read the selected value separately after settling: page.$eval(sel, el => el.value)

Example fix

// before
const vals = page.selectOption('#currency', 'EUR');

// after
try {
  page.selectOption('#currency', 'EUR');
} catch (e) {
  page.waitForLoadState('load'); // select triggered navigation
}
const val = page.$eval('#currency', el => el.value);
Defensive patterns

Strategy: try-catch

Validate before calling

const navigatesOnChange = page.$eval(sel, el => el.hasAttribute('onchange') || el.form?.hasAttribute('onchange'));
// if true, expect a navigation and verify state afterwards instead of trusting the return value

Try / catch

try {
  page.selectOption(sel, val);
} catch (e) {
  console.log(`selectOption read raced navigation: ${e}`);
  page.waitForLoadState('load');
  if (page.$eval(sel, el => el.value) !== val) throw new Error('selection not applied');
}

Prevention

When it happens

Trigger: The page navigates or the frame's execution context is destroyed in the window between the select action and the getProperties round-trip; or the CDP session/target is closed mid-call.

Common situations: An onchange handler on the <select> triggers navigation or a full page reload (e.g. a locale/currency picker); a form auto-submits on change; test teardown races the call.

Related errors


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

Appendix: source

Thrown at internal/js/modules/k6/browser/common/frame.go:1742

		return handle.selectOption(apiCtx, values)
	}
	act := f.newAction(
		selector, DOMElementStateAttached, opts.Strict, selectOption,
		[]string{}, opts.Force, withRetry, opts.NoWaitAfter, opts.Timeout,
	)
	v, err := call(f.ctx, act, opts.Timeout)
	if err != nil {
		return nil, errorFromDOMError(err)
	}
	selectHandle, ok := v.(jsHandle)
	if !ok {
		return nil, fmt.Errorf("unexpected select element type %T", v)
	}

	// pack the selected <option> values inside <select> into a slice
	optHandles, err := selectHandle.getProperties()
	if err != nil {
		return nil, fmt.Errorf("getProperties: %w", err)
	}
	vals := make([]string, 0, len(optHandles))
	for _, oh := range optHandles {
		val, err := oh.JSONValue()
		if err != nil {
			return nil, fmt.Errorf("reading value: %w", err)
		}
		vals = append(vals, val)
		if err := oh.dispose(); err != nil {
			return nil, fmt.Errorf("optionHandle.dispose: %w", err)
		}
	}
	if err := selectHandle.dispose(); err != nil {
		return nil, fmt.Errorf("selectHandle.dispose: %w", err)
	}

	return vals, nil
}

View on GitHub (pinned to 3fcf5388d7)