BookStackApp/BookStack · error · Error

Table column target index out of range

Error message

Table column target index out of range

What it means

$insertTableColumn iterates every TableRowNode and inserts columnCount new cells relative to targetIndex within each row. Because each row must supply a cell at targetIndex, the index must be a valid position in every row's children; if targetIndex >= the row's cell count or is negative, this error is thrown. It guards against inserting a column at a position that does not line up across all rows.

Source

Thrown at resources/js/wysiwyg/lexical/table/LexicalTableUtils.ts:335

export function $insertTableColumn(
  tableNode: TableNode,
  targetIndex: number,
  shouldInsertAfter = true,
  columnCount: number,
  table: TableDOMTable,
): TableNode {
  const tableRows = tableNode.getChildren();

  const tableCellsToBeInserted = [];
  for (let r = 0; r < tableRows.length; r++) {
    const currentTableRowNode = tableRows[r];

    if ($isTableRowNode(currentTableRowNode)) {
      for (let c = 0; c < columnCount; c++) {
        const tableRowChildren = currentTableRowNode.getChildren();
        if (targetIndex >= tableRowChildren.length || targetIndex < 0) {
          throw new Error('Table column target index out of range');
        }

        const targetCell = tableRowChildren[targetIndex];

        invariant($isTableCellNode(targetCell), 'Expected table cell');

        const {left, right} = $getTableCellSiblingsFromTableCellNode(
          targetCell,
          table,
        );

        let headerState = TableCellHeaderStates.NO_STATUS;

        if (
          (left && left.hasHeaderState(TableCellHeaderStates.ROW)) ||
          (right && right.hasHeaderState(TableCellHeaderStates.ROW))
        ) {
          headerState |= TableCellHeaderStates.ROW;

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Before calling, verify targetIndex < Math.min(...rows.map(r => r.getChildren().length)) and targetIndex >= 0.
  2. Prefer $insertTableColumn__EXPERIMENTAL(), which uses $computeTableMap and handles colspans/rowspans correctly.
  3. Clamp or recompute targetIndex from actual TableCellNode children rather than the DOM column index.
  4. Normalize tables with merged cells (convert colspan/rowspan into explicit cells) before using the non-experimental helper.

Example fix

// before
$insertTableColumn(tableNode, columnCount, true, 1, table);
// after
const minCells = Math.min(...tableNode.getChildren()
  .filter($isTableRowNode)
  .map(r => r.getChildren().length));
if (targetIndex < 0 || targetIndex >= minCells) return;
$insertTableColumn(tableNode, targetIndex, true, 1, table);
Defensive patterns

Strategy: validation

Validate before calling

function canInsertColumn(tableNode, targetIndex) {
  if (targetIndex < 0) return false;
  const rows = tableNode.getChildren().filter($isTableRowNode);
  return rows.every((r) => targetIndex < r.getChildren().length);
}

Type guard

function isValidColumnIndex(row, i) {
  return Number.isInteger(i) && i >= 0 && i < row.getChildren().length;
}

Try / catch

try {
  editor.update(() => $insertTableColumn(tableNode, targetIndex, true, 1, table));
} catch (e) {
  if (e.message === 'Table column target index out of range') {
    // fall back to experimental API which handles colspans
    editor.update(() => $insertTableColumn__EXPERIMENTAL());
  } else throw e;
}

Prevention

When it happens

Trigger: Calling $insertTableColumn(tableNode, targetIndex, ...) where at least one row has fewer cells than targetIndex+1 (e.g. rows built from colspan-bearing DOM where each TableRowNode holds fewer TableCellNodes than the visual column count), or passing targetIndex < 0.

Common situations: Computing targetIndex from the visual HTML column count while rows contain merged/colspan cells so logical cell counts differ; appending a column with targetIndex = columnCount (should be tableRows[0].getChildren().length - 1 or insertion at the end via a different path); calling on a table mutated by another plugin.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/da0882046d07912f. Report an issue: GitHub.