grafana/k6 · error

parsing browser.newContext options: %w

Error message

parsing browser.newContext options: %w

What it means

browser.newContext(opts) parses its argument with parseBrowserContextOptions: default BrowserContextOptions are merged with the passed value via Sobek ExportTo (mergeWith), then ProxyOptions.Validate runs (proxy.server must be set when a proxy object is given). This outer wrapper catches any failure in that pipeline - a struct export error for wrong field types, or 'proxy.server must be set'.

Source

Thrown at internal/js/modules/k6/browser/browser/browser_mapping.go:47

			return promise(vu, func() (any, error) {
				b, err := browser()
				if err != nil {
					return nil, err
				}
				return nil, b.CloseContext() //nolint:wrapcheck
			})
		},
		"isConnected": func() (bool, error) {
			b, err := browser()
			if err != nil {
				return false, err
			}
			return b.IsConnected(), nil
		},
		"newContext": func(opts sobek.Value) (*sobek.Promise, error) {
			popts, err := parseBrowserContextOptions(vu.Runtime(), opts)
			if err != nil {
				return nil, fmt.Errorf("parsing browser.newContext options: %w", err)
			}
			return promise(vu, func() (any, error) {
				b, err := browser()
				if err != nil {
					return nil, err
				}
				bctx, err := b.NewContext(popts)
				if err != nil {
					return nil, err //nolint:wrapcheck
				}
				if err := initBrowserContext(bctx, vu.testRunID); err != nil {
					return nil, err
				}

				return mapBrowserContext(vu, bctx), nil
			}), nil
		},
		"userAgent": func() (string, error) {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Match the documented BrowserContextOptions shape: viewport/screen as {width, height} numbers, booleans as real booleans, strings for locale/userAgent
  2. If passing proxy, always include server (e.g. { server: 'http://proxyhost:3128' })
  3. Read the wrapped cause after the colon - the ExportTo error names the offending field

Example fix

// before: wrong shapes for viewport and ignoreHTTPSErrors
const ctx = await browser.newContext({
  viewport: '1280x720',
  ignoreHTTPSErrors: 'true',
});

// after: correct types
const ctx = await browser.newContext({
  viewport: { width: 1280, height: 720 },
  ignoreHTTPSErrors: true,
});
Defensive patterns

Strategy: type-guard

Validate before calling

// validate the shape before calling newContext
function validContextOptions(o = {}) {
  const num = (v) => typeof v === 'number';
  if (o.viewport !== undefined && !(num(o.viewport.width) && num(o.viewport.height))) return false;
  if (o.screen !== undefined && !(num(o.screen.width) && num(o.screen.height))) return false;
  if (o.ignoreHTTPSErrors !== undefined && typeof o.ignoreHTTPSErrors !== 'boolean') return false;
  if (o.proxy !== undefined && (typeof o.proxy.server !== 'string' || !o.proxy.server)) return false;
  return true;
}
if (!validContextOptions(opts)) throw new TypeError('bad browser context options');
const ctx = await browser.newContext(opts);

Type guard

interface Viewport { width: number; height: number }
interface ContextOpts {
  viewport?: Viewport;
  screen?: Viewport;
  ignoreHTTPSErrors?: boolean;
  locale?: string;
  userAgent?: string;
  deviceScaleFactor?: number;
  proxy?: { server: string; bypass?: string };
}
function isContextOpts(v: unknown): v is ContextOpts {
  const o = v as ContextOpts;
  const vp = (x?: Viewport) => x == null || (typeof x.width === 'number' && typeof x.height === 'number');
  return (
    v != null && typeof v === 'object' && vp(o.viewport) && vp(o.screen) &&
    (o.ignoreHTTPSErrors == null || typeof o.ignoreHTTPSErrors === 'boolean') &&
    (o.proxy == null || typeof o.proxy.server === 'string')
  );
}

Try / catch

try {
  ctx = await browser.newContext(opts);
} catch (e) {
  if (String(e).includes('parsing browser.newContext options')) {
    // fall back to defaults, then apply only the subset you know is valid
    ctx = await browser.newContext();
  } else throw e;
}

Prevention

When it happens

Trigger: newContext({ viewport: '1280x720' }) - viewport must be {width, height} numbers; newContext({ ignoreHTTPSErrors: 'yes' }) - must be boolean; newContext({ proxy: { username: 'u' } }) - proxy without server fails validation; any value Sobek cannot export onto the options struct.

Common situations: Passing launch-time options (executablePath, headless) to newContext by mistake; stringified booleans/numbers from env-driven config; partial proxy configuration copied from system settings.

Related errors


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