{"record":{"id":"f725c263f105c495","repo":"overleaf/overleaf","slug":"missing-table-body","errorCode":null,"errorMessage":"Missing table body","messagePattern":"Missing table body","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/web/frontend/js/features/source-editor/components/table-generator/utils.ts","lineNumber":466,"sourceCode":"\nexport function generateTable(\n  node: SyntaxNode,\n  state: EditorState\n): ParsedTableData {\n  const specification = node\n    .getChild('BeginEnv')\n    ?.getChild('TextArgument')\n    ?.getChild('LongArg')\n\n  if (!specification) {\n    throw new Error('Missing column specification')\n  }\n  const columns = parseColumnSpecifications(\n    state.sliceDoc(specification.from, specification.to)\n  )\n  const body = node.getChild('Content')?.getChild('TabularContent')\n  if (!body) {\n    throw new Error('Missing table body')\n  }\n  const tableData = parseTabularBody(body, state)\n  const cellPositions = tableData.rows.map(row =>\n    row.cells.map(cell => cell.multiColumn?.position ?? cell.position)\n  )\n  const cellSeparators = tableData.rows.map(row => row.cellSeparators)\n  const rowPositions = tableData.rows.map(row => ({\n    ...row.position,\n    hlines: row.hlines.map(hline => hline.position),\n  }))\n  const rows = tableData.rows.map(row => ({\n    cells: row.cells.map(cell => {\n      const cellData: CellData = {\n        content: cell.content,\n        from: cell.position.from,\n        to: cell.position.to,\n      }\n      if (cell.multiColumn) {","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/web/frontend/js/features/source-editor/components/table-generator/utils.ts#L448-L484","documentation":"After extracting the column specification, generateTable looks for the Content > TabularContent node that holds the table's rows. If the tabular environment has no TabularContent child (no rows at all), there is nothing to render as a table, so it throws 'Missing table body'.","triggerScenarios":"Calling generateTable on an empty tabular environment like `\\begin{tabular}{ll}\\end{tabular}`, or one whose body was not parsed into a Content/TabularContent node due to a syntax error inside the environment.","commonSituations":"Deleting all table rows while hand-editing; a broken inner construct (unclosed brace or command) preventing TabularContent from parsing; scaffolding an empty table stub then triggering the generator.","solutions":["Add at least one row of content inside the tabular environment, e.g. `a & b \\\\`","Fix any syntax error inside the environment that prevents TabularContent from being parsed","Remove the empty tabular environment entirely if the table is not needed"],"exampleFix":"// before\n\\begin{tabular}{ll}\\end{tabular}\n// after\n\\begin{tabular}{ll}\n  a & b \\\\\n\\end{tabular}","handlingStrategy":"validation","validationCode":"function hasTableBody(latex) {\n  const m = /\\\\begin\\{tabular\\*?\\}[^]*?\\\\end\\{tabular\\*?\\}/.exec(latex);\n  return !!m && m[0].replace(/\\\\begin\\{tabular\\*?\\}[^]*?\\}/, '').trim().length > 0;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add at least one row before triggering table generation","Fix unbalanced braces inside the environment so the parser can build TabularContent","Remove empty tabular stubs instead of leaving them"],"tags":["latex","table-generator","syntax-tree"],"backgroundTag":"missing-table-body","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}