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
- Guard with the non-throwing $getTableNodeFromLexicalNode first and bail out when it returns null.
- Ensure the target node is currently attached under a TableNode before invoking table utilities.
- 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
- Gate table-specific commands on the selection actually intersecting a TableNode
- Use non-OrThrow variants ($getTableNodeFromLexicalNode) for optional contexts
- Avoid running table helpers on nodes from stale EditorStates
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
- Expected table cell to be inside of table row.
- Expected TableNode.
- Table row target index out of range
- Row before insertion index does not exist.
- Table column target index out of range
AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31).
Data as JSON: /api/errors/16feacbbd075ae0e.
Report an issue: GitHub.