{"record":{"id":"eab8a0a039e164cd","repo":"jestjs/jest","slug":"table-headings-do-not-conform-to-expected-format","errorCode":null,"errorMessage":"Table headings do not conform to expected format:\n\nheading1 | headingN\n\nReceived:\n\n${pretty(headings)}","messagePattern":"Table headings do not conform to expected format:\n\nheading1 \\| headingN\n\nReceived:\n\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-each/src/validation.ts","lineNumber":90,"sourceCode":"};\n\nconst pluralize = (word: string, count: number) =>\n  word + (count === 1 ? '' : 's');\n\nconst START_OF_LINE = '^';\nconst NEWLINE = '\\\\n';\nconst HEADING = '\\\\s*[^\\\\s]+\\\\s*';\nconst PIPE = '\\\\|';\nconst REPEATABLE_HEADING = `(${PIPE}${HEADING})*`;\nconst HEADINGS_FORMAT = new RegExp(\n  START_OF_LINE + NEWLINE + HEADING + REPEATABLE_HEADING + NEWLINE,\n  'g',\n);\n\nexport const extractValidTemplateHeadings = (headings: string): string => {\n  const matches = headings.match(HEADINGS_FORMAT);\n  if (matches === null) {\n    throw new Error(\n      `Table headings do not conform to expected format:\\n\\n${EXPECTED_COLOR(\n        'heading1 | headingN',\n      )}\\n\\nReceived:\\n\\n${RECEIVED_COLOR(pretty(headings))}`,\n    );\n  }\n\n  return matches[0];\n};\n","sourceCodeStart":72,"sourceCodeEnd":99,"githubUrl":"https://github.com/jestjs/jest/blob/8e6d128e4a278059ecddecaa97400b04c8ae5fd9/packages/jest-each/src/validation.ts#L72-L99","documentation":"Thrown by `extractValidTemplateHeadings` when the heading string does not match the expected pipe-delimited format regex (`^\\n\\s*\\S+\\s*(\\|\\s*\\S+\\s*)*\\n`). The heading row must be space-delimited tokens separated by pipes with newlines around them.","triggerScenarios":"Using commas instead of pipes (`` test.each`a, b\\n ${1} ${2}` ``), using a single heading with no pipe when multiple columns are needed, or having no surrounding newlines in the template structure. The regex match returns null.","commonSituations":"Migrating from comma-separated to pipe-separated format and forgetting to update the header. Using tab or semicolon delimiters. Missing the newline after the header row in the template literal.","solutions":["Format headings as pipe-separated: `` `a | b | c` `` with a newline before and after.","Ensure each heading is a non-whitespace token separated by ` | `.","Switch to array-of-arrays syntax if the template heading format is too finicky."],"exampleFix":"// before — commas instead of pipes\ntest.each`a, b\n  ${1} | ${2}`('test', ({a,b}) => {});\n\n// after — pipe-separated\ntest.each`a | b\n  ${1} | ${2}`('test', ({a,b}) => {});","handlingStrategy":"validation","validationCode":"// Validate heading format matches expected pipe-delimited pattern\nconst HEADING_RE = /^\\s*\\S+\\s*(\\|\\s*\\S+\\s*)*$/;\nfunction validateHeadingFormat(headings) {\n  if (!HEADING_RE.test(headings.trim())) {\n    throw new Error(`Headings must be pipe-separated: 'a | b | c', got: ${headings}`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the exact pipe-delimited format: token | token | token.","Switch to array-of-arrays syntax if template headings are difficult.","Copy a working .each template example as a starting point."],"tags":["jest-each","parameterized-tests","validation","tagged-template","format"],"backgroundTag":null,"analyzedSha":"8e6d128e4a278059ecddecaa97400b04c8ae5fd9","analyzedAt":"2026-08-10T18:11:27.960Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}