facebook/lexical · error

Node at cords not TableCellNode.

Error message

Node at cords not TableCellNode.

What it means

This accessor resolves coordinates to a TableCellNode via getCellNodeFromCords and throws 'Node at cords not TableCellNode.' when the lookup returns null. Unlike error 8, the DOM cell may exist but the corresponding node in the editor tree could not be resolved as a TableCellNode, typically due to a mismatch between the DOM table snapshot and the current node tree.

Source

Thrown at packages/lexical-table/src/LexicalTableNode.ts:791

    const node = $getNearestNodeFromDOMNode(cell.elem);

    if ($isTableCellNode(node)) {
      return node;
    }

    return null;
  }

  getCellNodeFromCordsOrThrow(
    x: number,
    y: number,
    table: TableDOMTable,
  ): TableCellNode {
    const node = this.getCellNodeFromCords(x, y, table);

    if (!node) {
      throw new Error('Node at cords not TableCellNode.');
    }

    return node;
  }

  getRowStriping(): boolean {
    return Boolean(this.getLatest().__rowStriping);
  }

  setRowStriping(newRowStriping: boolean): this {
    const self = this.getWritable();
    self.__rowStriping = newRowStriping;
    return self;
  }

  setFrozenColumns(columnCount: number): this {
    const self = this.getWritable();
    self.__frozenColumnCount = columnCount;

View on GitHub (pinned to 76a22dcba9)

Solutions

  1. Perform the lookup inside the same editor.update/read as the event that computed coordinates
  2. Recompute the TableDOMTable from the current DOM instead of caching it
  3. Use the non-throwing getCellNodeFromCords and handle null explicitly
  4. Ensure TableCellNode is registered on the editor so node resolution works

Example fix

// before
editor.read(() => {
  const node = table.getCellNodeAtCords(x, y, cachedDomTable); // throws on stale table
});

// after
editor.read(() => {
  const node = table.getCellNodeFromCords(x, y, table.getDOMCellFromCords ? currentDomTable : domTable);
  if (node) { /* handle */ }
});
Defensive patterns

Strategy: try-catch

Validate before calling

const node = table.getCellNodeFromCords(x, y, domTable); // non-throwing variant
if (node && $isTableCellNode(node)) { /* proceed */ }

Type guard

function isLiveTableCell(node: LexicalNode | null | undefined): node is TableCellNode {
  return $isTableCellNode(node) && node.isAttached();
}

Try / catch

try {
  const node = table.getCellNodeAtCords(x, y, domTable);
} catch (e) {
  if (String(e).includes('Node at cords not TableCellNode')) {
    // DOM snapshot out of sync with node tree — recompute inside current update
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling it with coordinates whose resolved key no longer maps to a live TableCellNode (cell deleted in a concurrent update); passing a TableDOMTable from a previous render; using it inside a read while a transform is mutating the table.

Common situations: Custom paste/merge plugins racing with table transforms; tables inside collaborative editing where another client removed cells; code reusing a TableDOMTable reference across update boundaries.

Related errors


AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31). Data as JSON: /api/errors/e9cb4c7f7687716a. Report an issue: GitHub.