grafana/k6 · error

reading value

Error message

reading value: %w

What it means

In frame.selectOption, each selected <option> handle's JSONValue() is called to serialize the option's value. This error means serialization of one option handle failed — the remote object could not be read because its context was destroyed or the handle became invalid.

Solutions

  1. Stabilize the component: avoid re-render storms on change, or select via keyboard/click steps
  2. Retry the whole selectOption after the page settles
  3. Verify the selection afterward with $eval instead of relying on the return array
  4. Increase the action timeout option so the read completes before any re-render

Example fix

// verify independently of the return value
page.selectOption('#size', 'L');
const chosen = page.$eval('#size', el => el.value);
if (chosen !== 'L') { throw new Error(`select failed, got ${chosen}`); }
Defensive patterns

Strategy: try-catch

Validate before calling

page.waitForSelector(`${sel} option`, { state: 'attached', timeout: 5000 }); // options populated

Try / catch

let vals = null;
try {
  vals = page.selectOption(sel, val);
} catch (e) {
  vals = [page.$eval(sel, el => el.value)]; // read value independently
}
if (!vals.includes(val)) throw new Error('selection not applied');

Prevention

When it happens

Trigger: The DOM mutates between selection and value read (options removed by a re-render), the page navigates mid-loop, or the CDP session drops while the option handles are being serialized.

Common situations: Framework-driven selects (React/Vue) that re-render options right after the change event; SPAs that route on select change; slow environments where the context times out.

Related errors


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

Appendix: source

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

	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
}

// SetContent replaces the entire HTML document content.
func (f *Frame) SetContent(html string, _ *FrameSetContentOptions) error {
	f.log.Debugf("Frame:SetContent", "fid:%s furl:%q", f.ID(), f.URL())

	// TODO(@inancgumus): Respect the FrameSetContentOptions before executing the action.

View on GitHub (pinned to 3fcf5388d7)