denoland/deno · error · ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "options.serializers" property must be an instance of Array. Received ${actual}

What it means

In node:test snapshot testing, t.assert.fileSnapshot(value, path, options) validates its options: if options.serializers is supplied it must be an Array (fileSnapshot assigns it element-by-element to run each serializer over the value). Passing anything else — most often a bare serializer function — throws ERR_INVALID_ARG_TYPE naming 'options.serializers' with expected type 'Array'. When omitted, the default file snapshot serializer is used.

Source

Thrown at ext/node/polyfills/testing.ts:342

// `t.assert.fileSnapshot(value, path[, options])`.
//
// Without `--test-update-snapshots`, serializes `value` and compares against
// the contents of the file at `path` using `assert.strictEqual`. With the
// flag, writes the serialized value to `path` (creating parent directories
// as needed). Both file paths are CWD-relative, matching Node.
function fileSnapshot(actual, path, options) {
  validateString(path, "path");
  if (options === undefined) {
    options = { __proto__: null };
  } else {
    validateObject(options, "options");
  }
  let serializers;
  if (options.serializers === undefined) {
    serializers = [defaultFileSnapshotSerializer];
  } else {
    if (!ArrayIsArray(options.serializers)) {
      throw new ERR_INVALID_ARG_TYPE(
        "options.serializers",
        "Array",
        options.serializers,
      );
    }
    serializers = options.serializers;
    for (let i = 0; i < serializers.length; i++) {
      if (typeof serializers[i] !== "function") {
        throw new ERR_INVALID_ARG_TYPE(
          `options.serializers[${i}]`,
          "function",
          serializers[i],
        );
      }
    }
  }
  let value = actual;
  try {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Wrap the serializer in an array: { serializers: [mySerializer] }
  2. Omit the serializers option entirely to use the default file snapshot serializer
  3. Order matters: serializers run left-to-right, each receiving the previous one's output — keep the array order intentional

Example fix

// before
t.assert.fileSnapshot(body, 'snap.txt', { serializers: mySerializer });

// after
t.assert.fileSnapshot(body, 'snap.txt', { serializers: [mySerializer] });
Defensive patterns

Strategy: validation

Validate before calling

function normalizeSerializers(options) {
  const serializers = options?.serializers;
  if (serializers === undefined) return undefined;
  if (!Array.isArray(serializers)) {
    throw new TypeError('options.serializers must be an Array');
  }
  return serializers;
}

const serializers = normalizeSerializers(opts);
t.assert.fileSnapshot(body, 'snap.txt', { serializers });

Type guard

const isSerializerArray = (v) =>
  v === undefined || (Array.isArray(v) && v.every((s) => typeof s === 'function'));

Prevention

When it happens

Trigger: t.assert.fileSnapshot(body, 'snap.txt', { serializers: mySerializer }) with a bare function instead of an array; passing a string, object, or null as serializers.

Common situations: Developers coming from APIs that accept a single function; copy-pasting a serializer from another test library; refactoring that drops the array brackets around an existing list.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/91baaebd1d695f71. Report an issue: GitHub.