microsoft/playwright · error · Error

Invalid timezone ID: ${timezoneId}

Error message

Invalid timezone ID: ${timezoneId}

What it means

Thrown by emulateTimezone (crPage.ts:1195) when Emulation.setTimezoneOverride fails with 'Invalid timezone' (and is not the benign 'already in effect' case). The timezoneId passed to newContext({ timezoneId }) is not accepted by Chromium — Playwright requires an IANA zone name.

Source

Thrown at packages/playwright-core/src/server/chromium/crPage.ts:1195

    await session.send('Emulation.setLocaleOverride', { locale });
  } catch (exception) {
    // All pages in the same renderer share locale. All such pages belong to the same
    // context and if locale is overridden for one of them its value is the same as
    // we are trying to set so it's not a problem.
    if (exception.message.includes('Another locale override is already in effect'))
      return;
    throw exception;
  }
}

async function emulateTimezone(session: CRSession, timezoneId: string) {
  try {
    await session.send('Emulation.setTimezoneOverride', { timezoneId: timezoneId });
  } catch (exception) {
    if (exception.message.includes('Timezone override is already in effect'))
      return;
    if (exception.message.includes('Invalid timezone'))
      throw new Error(`Invalid timezone ID: ${timezoneId}`);
    throw exception;
  }
}

// Chromium reference: https://source.chromium.org/chromium/chromium/src/+/main:components/embedder_support/user_agent_utils.cc;l=434;drc=70a6711e08e9f9e0d8e4c48e9ba5cab62eb010c2
export function calculateUserAgentMetadata(options: types.BrowserContextOptions) {
  const ua = options.userAgent;
  if (!ua)
    return undefined;
  const metadata: Protocol.Emulation.UserAgentMetadata = {
    mobile: !!options.isMobile,
    model: '',
    architecture: 'x86',
    platform: 'Windows',
    platformVersion: '',
  };
  const androidMatch = ua.match(/Android (\d+(\.\d+)?(\.\d+)?)/);
  const iPhoneMatch = ua.match(/iPhone OS (\d+(_\d+)?)/);

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Use an IANA zone such as 'America/Los_Angeles', 'Europe/Berlin', or 'UTC'.
  2. Validate before launch with Intl.supportedValuesOf('timeZone').includes(id).
  3. Check the spelling and capitalization — IANA names are case-sensitive in some engines.

Example fix

// before
const ctx = await browser.newContext({ timezoneId: 'PST' });
// after
const ctx = await browser.newContext({ timezoneId: 'America/Los_Angeles' });
Defensive patterns

Strategy: validation

Validate before calling

// Validate IANA zone before launch.
const id = 'America/Los_Angeles';
const valid = (Intl as any).supportedValuesOf
  ? (Intl as any).supportedValuesOf('timeZone').includes(id)
  : true; // fall back to a known-good list on older Node
if (!valid) throw new Error(`Unknown IANA timezone: ${id}`);
const ctx = await browser.newContext({ timezoneId: id });

Prevention

When it happens

Trigger: browser.newContext({ timezoneId: 'PST' }) or 'EST' / 'UTC+2' / a typo; passing a moment.js abbreviation; case-variant or locale names.

Common situations: Using timezone abbreviations instead of IANA IDs; copy-pasting zone names from non-IANA sources; testing on Chromium older than the zone database update.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/e2ba3c3027f3ebb5. Report an issue: GitHub.