facebook/lexical · error

Expected table cell to be inside of table.

Error message

Expected table cell to be inside of table.

What it means

$getTableNodeFromLexicalNodeOrThrow climbs from the starting node looking for an ancestor TableNode. If none exists, the node is not inside a table, so the OrThrow helper throws. This is a structural invariant check: callers require a table ancestor to compute indices or mutate the table.

Source

Thrown at packages/lexical-table/src/LexicalTableUtils.ts:128

  const node = $findMatchingParent(startingNode, n => $isTableRowNode(n));

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

  throw new Error('Expected table cell to be inside of table row.');
}

export function $getTableNodeFromLexicalNodeOrThrow(
  startingNode: LexicalNode,
): TableNode {
  const node = $findMatchingParent(startingNode, n => $isTableNode(n));

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

  throw new Error('Expected table cell to be inside of table.');
}

export function $getTableRowIndexFromTableCellNode(
  tableCellNode: TableCellNode,
): number {
  const tableRowNode = $getTableRowNodeFromTableCellNodeOrThrow(tableCellNode);
  const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableRowNode);
  return tableNode.getChildren().findIndex(n => n.is(tableRowNode));
}

export function $getTableColumnIndexFromTableCellNode(
  tableCellNode: TableCellNode,
): number {
  const tableRowNode = $getTableRowNodeFromTableCellNodeOrThrow(tableCellNode);
  return tableRowNode.getChildren().findIndex(n => n.is(tableCellNode));
}

export type TableCellSiblings = {

View on GitHub (pinned to 76a22dcba9)

Solutions

  1. Guard with the non-throwing $getTableNodeFromLexicalNode first and bail out when it returns null.
  2. Ensure the target node is currently attached under a TableNode before invoking table utilities.
  3. Re-derive the node from the active selection within editor.read/update rather than reusing cached references.

Example fix

// before
const table = $getTableNodeFromLexicalNodeOrThrow(someNode);
// after
const table = $getTableNodeFromLexicalNode(someNode);
if (table === null) return;
Defensive patterns

Strategy: type-guard

Validate before calling

const table = $getTableNodeFromLexicalNode(node);
if (table === null) return;

Type guard

function isInTable(node: LexicalNode): boolean {
  return $getTableNodeFromLexicalNode(node) !== null;
}

Try / catch

try {
  const table = $getTableNodeFromLexicalNodeOrThrow(node);
  // ...
} catch {
  // node is not inside a table; skip table logic
}

Prevention

When it happens

Trigger: Calling any $get...FromLexicalNodeOrThrow-style helper with a node that is not a descendant of a TableNode: detached nodes, root-level paragraphs mistakenly assumed to be table content, or cells removed during the same update.

Common situations: Running table utilities on selection content that only partially overlaps a table; applying table helpers after table deletion transforms; passing a TableNode's sibling rather than descendant.

Related errors


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