grafana/k6 · error

parsing inner HTML options: %w

Error message

parsing inner HTML options: %w

What it means

Thrown when locator.innerHTML(opts) fails to parse its options into FrameInnerHTMLOptions, which embeds FrameBaseOptions (strict boolean, timeout number in ms). The mapping wraps the cause as 'parsing inner HTML options: %w'. FrameBaseOptions.Parse in current k6 coerces values and ignores unknown keys, so the wrap is defensive and typically only reachable with an opts slot that is not a valid options object (or on stricter k6 versions).

Source

Thrown at internal/js/modules/k6/browser/browser/locator_mapping.go:307

			if k6common.IsNullish(title) {
				return nil, errors.New("missing required argument 'title'")
			}
			ptitle, popts := parseGetByBaseOptions(vu.Context(), title, false, opts)

			ml := mapLocator(vu, lo.GetByTitle(ptitle, popts))
			return rt.ToValue(ml).ToObject(rt), nil
		},
		"locator": func(selector string, opts sobek.Value) mapping {
			return mapLocator(vu, lo.Locator(selector, parseLocatorOptions(rt, opts)))
		},
		"frameLocator": func(selector string) *sobek.Object {
			mfl := mapFrameLocator(vu, lo.FrameLocator(selector))
			return rt.ToValue(mfl).ToObject(rt)
		},
		"innerHTML": func(opts sobek.Value) (*sobek.Promise, error) {
			copts := common.NewFrameInnerHTMLOptions(lo.Timeout())
			if err := copts.Parse(vu.Context(), opts); err != nil {
				return nil, fmt.Errorf("parsing inner HTML options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return lo.InnerHTML(copts) //nolint:wrapcheck
			}), nil
		},
		"innerText": func(opts sobek.Value) (*sobek.Promise, error) {
			copts := common.NewFrameInnerTextOptions(lo.Timeout())
			if err := copts.Parse(vu.Context(), opts); err != nil {
				return nil, fmt.Errorf("parsing inner text options: %w", err)
			}
			return promise(vu, func() (any, error) {
				return lo.InnerText(copts) //nolint:wrapcheck
			}), nil
		},
		"last": func() *sobek.Object {
			ml := mapLocator(vu, lo.Last())
			return rt.ToValue(ml).ToObject(rt)
		},

View on GitHub (pinned to 93accf6570)

Solutions

  1. Call innerHTML() with no arguments, or with a plain object: locator.innerHTML({ timeout: 5000 })
  2. Use numeric milliseconds for timeout, never strings like '5s'
  3. Remove keys that innerHTML does not support (only strict and timeout are read)
  4. Set a locator-wide default with locator.setDefaultTimeout(5000) to avoid per-call options

Example fix

// before
const html = await page.locator('#main').innerHTML('5s');

// after
const html = await page.locator('#main').innerHTML({ timeout: 5000 });
Defensive patterns

Strategy: validation

Validate before calling

function assertBaseOpts(method, opts) {
  if (opts === null || opts === undefined) return;
  if (typeof opts !== 'object' || Array.isArray(opts)) {
    throw new TypeError(`${method} options must be a plain object, got ${typeof opts}`);
  }
  if ('timeout' in opts && typeof opts.timeout !== 'number') {
    throw new TypeError(`${method} timeout must be a number (ms)`);
  }
}
assertBaseOpts('innerHTML', opts);

Type guard

function isLocatorBaseOptions(v) {
  if (v === null || v === undefined) return true;
  if (typeof v !== 'object' || Array.isArray(v)) return false;
  return (v.timeout === undefined || typeof v.timeout === 'number') &&
         (v.strict === undefined || typeof v.strict === 'boolean');
}

Try / catch

try {
  const html = await locator.innerHTML(opts);
} catch (e) {
  if (/parsing inner HTML options/.test(String(e.message))) {
    throw new Error(`Bad innerHTML options: ${JSON.stringify(opts)}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling page.locator('div#content').innerHTML('30s') or innerHTML(5000) — a scalar in the options slot; passing { timeout: '1m' } under a strict parser that expects a number; passing a selector or waitUntil string (not supported by innerHTML) from a copied Playwright waitForSelector call.

Common situations: Copy-pasting option objects between locator methods that accept different keys; passing a human-readable duration string instead of milliseconds; argument-order slips when scripting quickly.

Related errors


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