microsoft/playwright · error

serialize: expected an array of (Map|Set)

Error message

serialize: expected an array of (Map|Set)

What it means

assertEvaluateOptions validates the optional options bag passed to evaluate/evaluateHandle/$eval/$$eval/addInitScript. The 'serialize' option must be an array containing only the strings 'Map' or 'Set', naming which built-in types may round-trip through the call. Any non-array, or an array holding other values, is rejected with this error.

Solutions

  1. Wrap serialize in an array containing only 'Map' and/or 'Set': { serialize: ['Map', 'Set'] }.
  2. Remove the serialize option entirely — it is optional.
  3. Pass extra evaluated-function arguments via the arg parameter, not the options object.
  4. Check each entry is the exact string 'Map' or 'Set'.

Example fix

// before
await page.evaluate(fn, arg, { serialize: 'Map' });
// after
await page.evaluate(fn, arg, { serialize: ['Map', 'Set'] });
Defensive patterns

Strategy: validation

Validate before calling

function validSerializeOptions(options?: { serialize?: string[] }): boolean {
  return options?.serialize === undefined ||
    (Array.isArray(options.serialize) && options.serialize.every(t => t === 'Map' || t === 'Set'));
}

Type guard

function isSerializeArray(v: unknown): v is ('Map' | 'Set')[] {
  return Array.isArray(v) && v.every((t): t is 'Map' | 'Set' => t === 'Map' || t === 'Set');
}

Try / catch

try {
  await page.evaluate(fn, arg, { serialize: ['Map', 'Set'] });
} catch (e) {
  if ((e as Error).message.startsWith('serialize:')) {
    // fall back to no serialize option
    await page.evaluate(fn, arg);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling page.evaluate / locator.evaluate / frame.evaluate / evaluateHandle / $eval / $$eval / addInitScript with an options argument whose 'serialize' property is not an array of only 'Map' and 'Set' — e.g. { serialize: true }, { serialize: 'Map' }, { serialize: ['Map','Object'] }.

Common situations: Typos like serialize: 'Map' instead of ['Map'], copying options from a different feature's docs, passing 'Object' or 'Date' expecting support when only Map/Set are allowed, or stuffing extra evaluate arguments into the options object after seeing the 'Too many arguments' error.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of microsoft/playwright@f1d33b5029 (2026-09-21). Data as JSON: /api/errors/c356506414b9dfa6. Report an issue: GitHub.

Appendix: source

Thrown at packages/playwright-core/src/client/jsHandle.ts:153

    await Promise.all(exposePromises);
    return serialized;
  }, { internal: true });
}

export function parseResult(value: channels.SerializedValue): any {
  return parseSerializedValue(value, undefined);
}

export function assertMaxArguments(count: number, max: number): asserts count {
  if (count > max)
    throw new Error('Too many arguments. If you need to pass more than 1 argument to the function wrap them in an object.');
}

export function assertEvaluateOptions(options: any) {
  if (options !== undefined && (typeof options !== 'object' || options === null || Array.isArray(options)))
    throw new Error('Too many arguments. If you need to pass more than 1 argument to the function wrap them in an object.');
  if (options?.serialize !== undefined && (!Array.isArray(options.serialize) || options.serialize.some((type: unknown) => type !== 'Map' && type !== 'Set')))
    throw new Error('serialize: expected an array of (Map|Set)');
}

View on GitHub (pinned to f1d33b5029)