jestjs/jest · error · Error

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

Error message

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

What it means

The `install` helper in jest-each requires `.each` to be invoked with either a plain Array or a Tagged Template Literal. `bindingWithArray` is true when no extra template data is passed, and `bindingWithTemplate` requires the value to be an Array carrying a `.raw` property (the shape of a tagged template). If neither holds, the call is ambiguous and jest-each refuses to bind at index.ts:21.

Source

Thrown at packages/jest-each/src/index.ts:21

 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import type {Global} from '@jest/types';
import bind from './bind';

type Global = Global.Global;
const install = (
  g: Global,
  table: Global.EachTable,
  ...data: Global.TemplateData
) => {
  const bindingWithArray = data.length === 0;
  const bindingWithTemplate = Array.isArray(table) && !!(table as any).raw;
  if (!bindingWithArray && !bindingWithTemplate) {
    throw new Error(
      '`.each` must only be called with an Array or Tagged Template Literal.',
    );
  }
  const test = (
    title: string,
    test: Global.EachTestFn<Global.TestFn>,
    timeout?: number,
  ) => bind(g.test)(table, ...data)(title, test, timeout);
  test.skip = bind(g.test.skip)(table, ...data);
  test.only = bind(g.test.only)(table, ...data);

  const testConcurrent = (
    title: string,
    test: Global.EachTestFn<Global.TestFn>,
    timeout?: number,
  ) => bind(g.test.concurrent)(table, ...data)(title, test, timeout);

  test.concurrent = testConcurrent;

View on GitHub (pinned to f49721c78e)

Solutions

  1. Wrap the value in an array: `.each([value])`.
  2. If using a table object, convert to an array of row arrays first.
  3. For a tagged-template table, use the backtick call form: `.each\`head | val\n${row1}\`` rather than `.each(string)`.
  4. Double-check you are calling `.each` (table) then `(title, fn)`, not collapsing the two calls.

Example fix

// before
describe.each(myObject)('case %s', (row) => {});

// after
describe.each(Object.values(myObject))('case %j', (row) => {});
Defensive patterns

Strategy: type-guard

Validate before calling

// wrap .each so misuse is caught with a clear message before binding
function safeEach(table) {
  const isArr = Array.isArray(table);
  const isTpl = isArr && Object.prototype.hasOwnProperty.call(table, 'raw');
  if (!isArr && !(isArr && isTpl)) throw new TypeError('each() needs Array or tagged template');
  return realEach(table);
}

Type guard

const isEachTable = (t: unknown): t is unknown[] | TemplateStringsArray => Array.isArray(t);

Prevention

When it happens

Trigger: Calling `describe.each(42)(...)`, `.each(someObject)(...)`, `.each(myFunction)(...)`, or `.each('plain string')(...)` — anything that is not an array and not a tagged template expression.

Common situations: Passing a single primitive where an array was intended (`each(1)` instead of `each([1])`); passing a Map/Set/Object expecting spread semantics; refactoring that drops the array wrapper; using a generator/iterator directly.

Related errors


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