Skip to content

[lexical-website] Documentation Update: guard node references in later callbacks - #9268

Open
ZedingZhang wants to merge 1 commit into
facebook:mainfrom
ZedingZhang:docs/9111-node-references
Open

ZedingZhang wants to merge 1 commit into
facebook:mainfrom
ZedingZhang:docs/9111-node-references

Conversation

@ZedingZhang

Copy link
Copy Markdown

Description

A callback can retain a non-null node reference after the node has been removed from the editor state. The key-management FAQ mentions the possible error but does not show where to check the node before using it.

Document both supported patterns: resolve a captured NodeKey in the later update, or guard an existing node reference with isAttached() inside that update. Explain the difference between a missing key and a detached node, keep checks and usage in the same read/update context, and link the examples from the editor-state guide. Clarify that the constructor/clone guidance concerns direct __key access, not application-level key lookup.

Related to #9111. This addresses the suggested documentation improvement; it does not implement the proposed lint rule.

Prepared and validated with Codex assistance.

Test plan

Before

A local headless probe against current source reproduced the removed-node error from unguarded getLatest() access:

REPRO key: unguarded access throws after removal
REPRO reference: unguarded access throws after removal

After

Extracted both TypeScript snippets from the Markdown and checked them against the current source with TypeScript and Prettier. Executed them in a local headless probe:

PASS key: selects attached node
PASS key: resolves latest node version
PASS key: removed node is a no-op without throwing
PASS reference: selects attached node
PASS reference: resolves latest node version
PASS reference: removed node is a no-op without throwing

Website TypeScript checking and the package build passed. Docusaurus generated both edited pages; checked that the new heading, code snippets, and cross-page anchor are present in the generated HTML. git diff --check passed.

Full website build is not green locally on Windows / Node 24.19.0: pnpm -C packages/lexical-website run build stops in the existing dev-example script with Error: spawnSync npx ENOENT. After running those Vite builds directly and building the documentation examples, pnpm -C packages/lexical-website run docusaurus build renders the pages but fails broken-link validation because TypeDoc rejects the existing backslash-separated entry-point paths (Glob inputs to TypeDoc may not use Windows path separators) and leaves API pages missing. No build configuration was changed. Linux/macOS builds were not run locally.

…r callbacks

## Description

A callback can retain a non-null node reference after the node has been removed from the editor state. The key-management FAQ mentions the possible error but does not show where to check the node before using it.

Document both supported patterns: resolve a captured NodeKey in the later update, or guard an existing node reference with isAttached() inside that update. Explain the difference between a missing key and a detached node, keep checks and usage in the same read/update context, and link the examples from the editor-state guide. Clarify that the constructor/clone guidance concerns direct __key access, not application-level key lookup.

Related to facebook#9111. This addresses the suggested documentation improvement; it does not implement the proposed lint rule.

Prepared and validated with Codex assistance.

## Test plan

### Before

A local headless probe against current source reproduced the removed-node error from unguarded getLatest() access:

```text
REPRO key: unguarded access throws after removal
REPRO reference: unguarded access throws after removal
```

### After

Extracted both TypeScript snippets from the Markdown and checked them against the current source with TypeScript and Prettier. Executed them in a local headless probe:

```text
PASS key: selects attached node
PASS key: resolves latest node version
PASS key: removed node is a no-op without throwing
PASS reference: selects attached node
PASS reference: resolves latest node version
PASS reference: removed node is a no-op without throwing
```

Website TypeScript checking and the package build passed. Docusaurus generated both edited pages; checked that the new heading, code snippets, and cross-page anchor are present in the generated HTML. `git diff --check` passed.

Full website build is not green locally on Windows / Node 24.19.0: `pnpm -C packages/lexical-website run build` stops in the existing dev-example script with `Error: spawnSync npx ENOENT`. After running those Vite builds directly and building the documentation examples, `pnpm -C packages/lexical-website run docusaurus build` renders the pages but fails broken-link validation because TypeDoc rejects the existing backslash-separated entry-point paths (`Glob inputs to TypeDoc may not use Windows path separators`) and leaves API pages missing. No build configuration was changed. Linux/macOS builds were not run locally.
@ZedingZhang
ZedingZhang requested a review from zurfyx as a code owner September 29, 2026 06:35
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 29, 2026
@vercel

vercel Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
lexical Ready Ready Preview Sep 29, 2026 6:37am UTC
lexical-playground Ready Ready Preview Sep 29, 2026 6:37am UTC

Request Review

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessarily the best guidance, as long as you check isAttached first it's fine to use a reference even if the node is not in the current NodeMap. The implementation of isAttached has no dependency on getLatest or getWritable and will never throw.

This branch was successfully deployed

2 active deployments
Preview – lexical — 9ef1cf82 Deployed Sep 29, 2026 by vercel[bot]
Preview – lexical-playground — 9ef1cf82 Deployed Sep 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants