grafana/k6 · error

parse isEditable options of selector

Error message

parse isEditable options of selector %q: %w

What it means

Thrown when `frame.isEditable(selector, opts)` options fail to parse into FrameIsEditableOptions (FrameBaseOptions: `strict`, `timeout` ms). Message includes the selector and uses the wording "parse isEditable options" (most siblings say "parsing"). Parse is coercive today, so the branch is defensive.

Solutions

  1. Pass { strict: bool, timeout: number_ms }
  2. Sanitize config-sourced options (JSON/env) before passing them to browser APIs
  3. Grep logs for the exact 'parse isEditable options' wording — it is unique to this call

Example fix

// before
await frame.isEditable('#tb', { timeout: Number('abc') }); // NaN -> 0

// after
await frame.isEditable('#tb', { timeout: 3000 });
Defensive patterns

Strategy: try-catch

Validate before calling

const opts = { timeout: 3000 };
if (opts.timeout != null && !Number.isInteger(opts.timeout)) console.warn('non-integer timeout may coerce unexpectedly');

Type guard

function isFrameBaseOptions(o) {
  return o == null || (typeof o === 'object' && (o.timeout === undefined || Number.isFinite(o.timeout)));
}

Try / catch

try {
  await frame.isEditable(sel, opts);
} catch (e) {
  if (String(e).includes('parse isEditable options')) { /* note: this message says parse, not parsing */ } else { throw e; }
}

Prevention

When it happens

Trigger: Not reachable with the current coercive Parse; would require strict validation of `strict`/`timeout` types.

Common situations: Ported Playwright scripts with unsupported keys; env-driven config injecting strings into the options object.

Related errors


AI-assisted analysis of grafana/k6@8d06114777 (2026-09-14). Data as JSON: /api/errors/22ee99b1ce637705. Report an issue: GitHub.

Appendix: source

Thrown at internal/js/modules/k6/browser/browser/frame_mapping.go:274

			}
			return promise(vu, func() (any, error) {
				return f.IsChecked(selector, popts) //nolint:wrapcheck
			}), nil
		},
		"isDetached": f.IsDetached,
		"isDisabled": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameIsDisabledOptions(rt, opts, f.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parsing isDisabled options of selector %q: %w", selector, err)
			}
			return promise(vu, func() (any, error) {
				return f.IsDisabled(selector, popts) //nolint:wrapcheck
			}), nil
		},
		"isEditable": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameIsEditableOptions(rt, opts, f.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parse isEditable options of selector %q: %w", selector, err)
			}
			return promise(vu, func() (any, error) {
				return f.IsEditable(selector, popts) //nolint:wrapcheck
			}), nil
		},
		"isEnabled": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameIsEnabledOptions(rt, opts, f.Timeout())
			if err != nil {
				return nil, fmt.Errorf("parse isEnabled options of selector %q: %w", selector, err)
			}
			return promise(vu, func() (any, error) {
				return f.IsEnabled(selector, popts) //nolint:wrapcheck
			}), nil
		},
		"isHidden": func(selector string, opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseFrameIsHiddenOptions(rt, opts)
			if err != nil {
				return nil, fmt.Errorf("parse isHidden options of selector %q: %w", selector, err)

View on GitHub (pinned to 8d06114777)