grafana/k6 · error

emulating locale %q: %w

Error message

emulating locale %q: %w

What it means

FrameSession.emulateLocale (frame_session.go:202) sends Emulation.setLocaleOverride with the `locale` browser-context option. Chromium rejects malformed/unsupported locale strings (other than the 'already in effect' error, which is swallowed), and the failure is wrapped with the offending locale. The error surfaces during page/session initialization, so the page never opens.

Source

Thrown at internal/js/modules/k6/browser/common/frame_session.go:202

	if err = fs.initDomains(); err != nil {
		l.Debugf(
			"NewFrameSession:initDomains",
			"sid:%v tid:%v err:%v",
			s.ID(), tid, err)

		return nil, err
	}

	return &fs, nil
}

func (fs *FrameSession) emulateLocale() error {
	action := emulation.SetLocaleOverride().WithLocale(fs.page.browserCtx.opts.Locale)
	if err := action.Do(cdp.WithExecutor(fs.ctx, fs.session)); err != nil {
		if strings.Contains(err.Error(), "Another locale override is already in effect") {
			return nil
		}
		return fmt.Errorf("emulating locale %q: %w", fs.page.browserCtx.opts.Locale, err)
	}
	return nil
}

func (fs *FrameSession) emulateTimezone() error {
	action := emulation.SetTimezoneOverride(fs.page.browserCtx.opts.TimezoneID)
	if err := action.Do(cdp.WithExecutor(fs.ctx, fs.session)); err != nil {
		if strings.Contains(err.Error(), "Timezone override is already in effect") {
			return nil
		}
		return fmt.Errorf("emulating timezone %q: %w", fs.page.browserCtx.opts.TimezoneID, err)
	}
	return nil
}

func (fs *FrameSession) getNetworkManager() *NetworkManager {
	return fs.networkManager
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Use a BCP-47 locale with a hyphen, e.g. 'en-US', 'fr-FR', 'de-DE'
  2. Verify the locale is supported by chromium/ICU before passing it (see validation snippet)
  3. If you do not actually need locale emulation, omit the option entirely

Example fix

// before
const ctx = browser.newContext({ locale: 'en_US' });

// after
const ctx = browser.newContext({ locale: 'en-US' });
Defensive patterns

Strategy: validation

Validate before calling

function validLocale(l) {
  if (!l) return l;
  if (!/^[a-z]{2,3}(-[A-Z]{2}|-[0-9A-Za-z]+)*$/i.test(l)) {
    throw new Error(`locale looks invalid (use BCP-47 like 'en-US'): ${l}`);
  }
  return l;
}
browser.newContext({ locale: validLocale(cfg.locale) });

Type guard

function isBcp47Locale(v: unknown): v is string {
  return typeof v === 'string' && /^[a-z]{2,3}(-[A-Z][a-z]{3})?(-([A-Z]{2}|\d{3}))?$/i.test(v);
}

Prevention

When it happens

Trigger: browser.newContext({ locale: 'xx-XX' }) or a locale Chromium does not recognize (e.g. 'en_US' with an underscore, empty string passed explicitly, or free-text like 'english'). Locale comes from the context options and is applied per frame session.

Common situations: Underscore vs hyphen confusion (ICU/Java style 'en_US' instead of BCP-47 'en-US'), locales valid on the developer's OS but not compiled into the bundled chromium build, or values coming from config without validation.

Related errors


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