jestjs/jest · error · TypeError

`.each` must be called with an Array or Tagged Template Lite

Error message

`.each` must be called with an Array or Tagged Template Literal.

Instead was called with: ${pretty(table, {maxDepth: 1, min: true})}

What it means

validateArrayTable runs deeper validation on the array path of jest-each. The first guard re-checks that the supplied table is actually an Array; if it is not, it reports the offending value (pretty-formatted at maxDepth 1) so the user can see exactly what was passed. This is a stricter, more informative sibling of the index.ts check.

Source

Thrown at packages/jest-each/src/validation.ts:20

 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import chalk from 'chalk';
import type {Global} from '@jest/types';
import {format as pretty} from 'pretty-format';

type TemplateData = Global.TemplateData;

const EXPECTED_COLOR = chalk.green;
const RECEIVED_COLOR = chalk.red;

export const validateArrayTable = (table: unknown): void => {
  if (!Array.isArray(table)) {
    throw new TypeError(
      '`.each` must be called with an Array or Tagged Template Literal.\n\n' +
        `Instead was called with: ${pretty(table, {
          maxDepth: 1,
          min: true,
        })}\n`,
    );
  }

  if (isTaggedTemplateLiteral(table)) {
    if (isEmptyString(table[0])) {
      throw new Error(
        'Error: `.each` called with an empty Tagged Template Literal of table data.\n',
      );
    }

    throw new Error(
      'Error: `.each` called with a Tagged Template Literal with no data, remember to interpolate with ${expression} syntax.\n',
    );

View on GitHub (pinned to f49721c78e)

Solutions

  1. Inspect the `Instead was called with:` line to see the actual value, then fix its source.
  2. Guard the helper: `const table = await getRows(); if (!Array.isArray(table)) throw ...`.
  3. If the value is a Promise, add `await` before passing it.
  4. If it is an array-like, convert with `Array.from(...)`.

Example fix

// before
const rows = fetchRows(); // returns a Promise
it.each(rows)('row %j', (r) => {});

// after
const rows = await fetchRows();
it.each(rows)('row %j', (r) => {});
Defensive patterns

Strategy: validation

Validate before calling

const table = await getRows();
if (!Array.isArray(table)) {
  throw new TypeError(`each() expected array, got ${typeof table}`);
}
it.each(table)(...);

Type guard

const isRowArray = (t: unknown): t is unknown[] => Array.isArray(t);

Prevention

When it happens

Trigger: Reaching bind's array branch with a non-array — typically by manually constructing a table variable that was expected to be an array but resolved to undefined/null/object, or by spreading incorrectly so the table slot receives a non-array.

Common situations: A helper returns `undefined` on an edge case and you pass it straight to `.each`; an async/await omission means a Promise is passed instead of the resolved array; default-export interop returns the module namespace object instead of the array.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/483b86f48e5c366e.json. Report an issue: GitHub.