overleaf/overleaf · error

Invalid multicolumn definition: multicolumn must be at the s

Error message

Invalid multicolumn definition: multicolumn must be at the start of a cell

What it means

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.

Source

Thrown at services/web/frontend/js/features/source-editor/components/table-generator/utils.ts:327

        ?.getChild('ShortArg')
      const tabularArgument = multiColumn
        .getChild('TabularArgument')
        ?.getChild('TabularContent')
      if (!columnArgument) {
        throw new Error(
          'Invalid multicolumn definition: missing column specification argument'
        )
      }
      if (!spanArgument) {
        throw new Error(
          'Invalid multicolumn definition: missing colspan argument'
        )
      }
      if (!tabularArgument) {
        throw new Error('Invalid multicolumn definition: missing cell content')
      }
      if (getLastCell()?.content.trim()) {
        throw new Error(
          'Invalid multicolumn definition: multicolumn must be at the start of a cell'
        )
      }
      const columnSpecification = parseColumnSpecifications(
        state.sliceDoc(columnArgument.from, columnArgument.to)
      )
      const span = parseInt(state.sliceDoc(spanArgument.from, spanArgument.to))
      const cellContent = state.sliceDoc(
        tabularArgument.from,
        tabularArgument.to
      )
      if (!getLastCell()) {
        getLastRow().cells.push({
          content: '',
          position: { from: currentChild.from, to: currentChild.from },
        })
      }
      const lastCell = getLastCell()!

View on GitHub (pinned to 28ad3b03b7)

Solutions

  1. Move the \multicolumn so it starts the cell: replace 'text \multicolumn{...}' with 'text & \multicolumn{...}'
  2. Remove the preceding text or place it in its own cell before the \multicolumn
  3. Use the table editor's merge-cells UI rather than typing \multicolumn manually
  4. Split the row: put existing content in separate cells and start the merged cell fresh

Example fix

// before
Lorem ipsum & \multicolumn{2}{c}{Merged} \\
// after
Lorem ipsum & \multicolumn{2}{c}{Merged} \\ % multicolumn starts its own cell
% or: Lorem & ipsum & \multicolumn{2}{c}{Merged} \\
Defensive patterns

Strategy: validation

Validate before calling

function multicolumnStartsCell(rowText: string): boolean {
  const idx = rowText.indexOf('\\multicolumn')
  if (idx === -1) return true
  return rowText.slice(0, idx).replace(/&/g, '').trim() === ''
}
if (!multicolumnStartsCell(row)) reorderCells()

Try / catch

try {
  parseTabularBody(doc, state)
} catch (e) {
  if (e.message.includes('multicolumn must be at the start of a cell')) return null
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03). Data as JSON: /api/errors/95a45035c5a37d00. Report an issue: GitHub.