BookStackApp/BookStack · error · Error

Cell not found in table.

Error message

Cell not found in table.

What it means

TableNode.getCordsFromCellNode maps a TableCellNode to its (x, y) grid coordinates by scanning the table's cell map. If the given cell node does not belong to this table (or its coordinates can't be resolved), no x is found and the method throws 'Cell not found in table.'

Source

Thrown at resources/js/wysiwyg/lexical/table/LexicalTableNode.ts:224

      if (row == null) {
        continue;
      }

      const x = row.findIndex((cell) => {
        if (!cell) {
          return;
        }
        const {elem} = cell;
        const cellNode = $getNearestNodeFromDOMNode(elem);
        return cellNode === tableCellNode;
      });

      if (x !== -1) {
        return {x, y};
      }
    }

    throw new Error('Cell not found in table.');
  }

  getDOMCellFromCords(
    x: number,
    y: number,
    table: TableDOMTable,
  ): null | TableDOMCell {
    const {domRows} = table;

    const row = domRows[y];

    if (row == null) {
      return null;
    }

    const index = x < row.length ? x : row.length - 1;

    const cell = row[index];

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Verify the TableCellNode belongs to the same TableNode (check its parent chain) before calling getCordsFromCellNode.
  2. Re-read the cell node with $getNodeByKey inside the current update cycle instead of reusing cached references.
  3. Use the non-throwing lookup (scan the grid yourself or use getCellNodeFromCords returning null) and handle the null case.
  4. Recompute coordinates after any table structure mutation (row/column insert/delete).

Example fix

// before
const {x, y} = tableNode.getCordsFromCellNode(cellNode); // throws for foreign cell

// after
if ($isTableCellNode(cellNode) && cellNode.getParentTable() === tableNode) {
  const {x, y} = tableNode.getCordsFromCellNode(cellNode);
}
Defensive patterns

Strategy: type-guard

Validate before calling

function cellBelongsToTable(cell: TableCellNode, table: TableNode): boolean {
  let p = cell.getParent();
  while (p) { if (p === table) return true; p = p.getParent(); }
  return false;
}

Type guard

function $isCellInTable(cell: LexicalNode | null | undefined, table: TableNode): cell is TableCellNode {
  return $isTableCellNode(cell) && cell.getParentTable?.() === table;
}

Try / catch

try {
  const {x, y} = tableNode.getCordsFromCellNode(cellNode);
} catch (e) {
  if (e instanceof Error && e.message === 'Cell not found in table.') {
    return null; // stale/foreign cell — recompute
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a TableCellNode from a different table, a cell node that has been removed/replaced in the DOM (stale key), or a cell whose row was deleted so it no longer appears in the grid map.

Common situations: Selection code holding a reference to a cell node from before a table mutation (insert/delete row/column); iterating cached nodes after an editor.update removed them; accidentally passing a cell from a nested/different table.

Related errors


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