{"id":"875170f367bff26c","repo":"jestjs/jest","slug":"error-each-called-with-a-tagged-template-liter","errorCode":null,"errorMessage":"Error: `.each` called with a Tagged Template Literal with no data, remember to interpolate with ${expression} syntax.\n","messagePattern":"Error: `\\.each` called with a Tagged Template Literal with no data, remember to interpolate with (.+?) syntax\\.\n","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-each/src/validation.ts","lineNumber":36,"sourceCode":"export const validateArrayTable = (table: unknown): void => {\n  if (!Array.isArray(table)) {\n    throw new TypeError(\n      '`.each` must be called with an Array or Tagged Template Literal.\\n\\n' +\n        `Instead was called with: ${pretty(table, {\n          maxDepth: 1,\n          min: true,\n        })}\\n`,\n    );\n  }\n\n  if (isTaggedTemplateLiteral(table)) {\n    if (isEmptyString(table[0])) {\n      throw new Error(\n        'Error: `.each` called with an empty Tagged Template Literal of table data.\\n',\n      );\n    }\n\n    throw new Error(\n      'Error: `.each` called with a Tagged Template Literal with no data, remember to interpolate with ${expression} syntax.\\n',\n    );\n  }\n\n  if (isEmptyTable(table)) {\n    throw new Error(\n      'Error: `.each` called with an empty Array of table data.\\n',\n    );\n  }\n};\n\nconst isTaggedTemplateLiteral = (array: any) => array.raw !== undefined;\nconst isEmptyTable = (table: Array<unknown>) => table.length === 0;\nconst isEmptyString = (str: string | unknown) =>\n  typeof str === 'string' && str.trim() === '';\n\nexport const validateTemplateTableArguments = (\n  headings: Array<string>,","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-each/src/validation.ts#L18-L54","documentation":"The tagged-template branch in validateArrayTable is also taken when the template has a non-empty first string but jest-each concludes there is no interpolated data. The fix message reminds the user that data must be supplied via `${expression}` interpolation inside the template; without interpolations the table has headings but zero rows.","triggerScenarios":"Calling `.each\\`a | b\\`` — a header line with no `${...}` interpolations — so the `data` rest parameter is empty and there are no rows to iterate.","commonSituations":"Author writes the header row but forgets to interpolate row values; copy-paste of a header from documentation without filling in data; dynamic data computed but never interpolated into the template.","solutions":["Add `${row}` interpolations after the header line, one per data row.","If the data is in an array, switch to the array form `.each(rows)` instead of a tagged template.","For array-of-objects data use `.each(rows)('...$field...', row => {})`."],"exampleFix":"// before\nit.each`\n  a | b\n`('$a/$b', ({a,b}) => {});\n\n// after\nit.each`\n  a    | b\n  ${1} | ${2}\n  ${3} | ${4}\n`('$a/$b', ({a,b}) => {});","handlingStrategy":"validation","validationCode":"// ensure at least one interpolation slot when authoring tagged templates\nconst hasInterpolations = (strings: TemplateStringsArray, ...vals: unknown[]) => vals.length > 0;","typeGuard":"const hasRowData = (strings: TemplateStringsArray, vals: unknown[]) => vals.length > 0;","tryCatchPattern":null,"preventionTips":["After writing the header, immediately add at least one ${row} line.","Prefer the array form when data is already an array.","Use a code generator for parameterized tables."],"tags":["jest-each","parameterized-tests","tagged-template","validation"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}