{"record":{"id":"95a45035c5a37d00","repo":"overleaf/overleaf","slug":"invalid-multicolumn-definition-multicolumn-must-b","errorCode":null,"errorMessage":"Invalid multicolumn definition: multicolumn must be at the start of a cell","messagePattern":"Invalid multicolumn definition: multicolumn must be at the start of a cell","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"services/web/frontend/js/features/source-editor/components/table-generator/utils.ts","lineNumber":327,"sourceCode":"        ?.getChild('ShortArg')\n      const tabularArgument = multiColumn\n        .getChild('TabularArgument')\n        ?.getChild('TabularContent')\n      if (!columnArgument) {\n        throw new Error(\n          'Invalid multicolumn definition: missing column specification argument'\n        )\n      }\n      if (!spanArgument) {\n        throw new Error(\n          'Invalid multicolumn definition: missing colspan argument'\n        )\n      }\n      if (!tabularArgument) {\n        throw new Error('Invalid multicolumn definition: missing cell content')\n      }\n      if (getLastCell()?.content.trim()) {\n        throw new Error(\n          'Invalid multicolumn definition: multicolumn must be at the start of a cell'\n        )\n      }\n      const columnSpecification = parseColumnSpecifications(\n        state.sliceDoc(columnArgument.from, columnArgument.to)\n      )\n      const span = parseInt(state.sliceDoc(spanArgument.from, spanArgument.to))\n      const cellContent = state.sliceDoc(\n        tabularArgument.from,\n        tabularArgument.to\n      )\n      if (!getLastCell()) {\n        getLastRow().cells.push({\n          content: '',\n          position: { from: currentChild.from, to: currentChild.from },\n        })\n      }\n      const lastCell = getLastCell()!","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/services/web/frontend/js/features/source-editor/components/table-generator/utils.ts#L309-L345","documentation":"A \\multicolumn can only be the first thing in its table cell, since it defines a brand-new merged cell. parseTabularBody checks getLastCell()?.content — if the current cell already has non-whitespace content, throwing this Error prevents merging that would silently corrupt the table layout.","triggerScenarios":"Writing \\multicolumn after other text in the same cell, e.g. 'text \\multicolumn{2}{c}{X}' or 'a & b \\multicolumn{2}{c}{c}', so the preceding cell content is non-empty when the macro is parsed.","commonSituations":"Appending a \\multicolumn at the end of a row's last cell instead of starting a new cell; editing cells by hand after the generator inserted one; copy-pasting a \\multicolumn into the middle of existing text.","solutions":["Move the \\multicolumn so it starts the cell: replace 'text \\multicolumn{...}' with 'text & \\multicolumn{...}'","Remove the preceding text or place it in its own cell before the \\multicolumn","Use the table editor's merge-cells UI rather than typing \\multicolumn manually","Split the row: put existing content in separate cells and start the merged cell fresh"],"exampleFix":"// before\nLorem ipsum & \\multicolumn{2}{c}{Merged} \\\\\n// after\nLorem ipsum & \\multicolumn{2}{c}{Merged} \\\\ % multicolumn starts its own cell\n% or: Lorem & ipsum & \\multicolumn{2}{c}{Merged} \\\\","handlingStrategy":"validation","validationCode":"function multicolumnStartsCell(rowText: string): boolean {\n  const idx = rowText.indexOf('\\\\multicolumn')\n  if (idx === -1) return true\n  return rowText.slice(0, idx).replace(/&/g, '').trim() === ''\n}\nif (!multicolumnStartsCell(row)) reorderCells()","typeGuard":null,"tryCatchPattern":"try {\n  parseTabularBody(doc, state)\n} catch (e) {\n  if (e.message.includes('multicolumn must be at the start of a cell')) return null\n  throw e\n}","preventionTips":["Only place \\multicolumn immediately after a '&' or at row start","Use the merge-cells UI so positioning is enforced automatically","Avoid pasting \\multicolumn into the middle of existing cell text","Add positioning-violation fixtures to parser tests"],"tags":["latex","multicolumn","table-generator","parse-error"],"backgroundTag":"malformed-multicolumn","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}