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
- Before calling, verify targetIndex < Math.min(...rows.map(r => r.getChildren().length)) and targetIndex >= 0.
- Prefer $insertTableColumn__EXPERIMENTAL(), which uses $computeTableMap and handles colspans/rowspans correctly.
- Clamp or recompute targetIndex from actual TableCellNode children rather than the DOM column index.
- 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
- Never derive the target index from the visual DOM column count when colspan/rowspan cells exist.
- Prefer $insertTableColumn__EXPERIMENTAL() which uses the computed table map.
- Clamp the index against the minimum per-row cell count before every call.
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
- Row before insertion index does not exist.
- Cell not found in table.
- Cell not found at cords.
- Node at cords not TableCellNode.
- Table Element Not Found
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/da0882046d07912f.
Report an issue: GitHub.