facebook/lexical · warning
${name} must implement static "${method}" method
Error message
${name} must implement static "${method}" method What it means
When createEditor processes the `nodes` array, each node class must define its own static `getType` and `clone` methods (inherited ones are rejected via hasOwnStaticMethod, except LexicalNode itself). If a class lacks one, Lexical logs this warning; such a node will misbehave (getType/clone falls back to the parent's, producing wrong types or broken cloning).
Source
Thrown at packages/lexical/src/LexicalEditor.ts:1037
name,
);
} else if (replace) {
console.warn(
`Override for ${name} specifies 'replace' without 'withKlass'. 'withKlass' will be required in a future version.`,
);
}
if (
name !== 'RootNode' &&
nodeType !== 'root' &&
nodeType !== 'artificial' &&
// This is mostly for the unit test suite which
// uses LexicalNode in an otherwise incorrect way
// by mocking its static getType
klass !== LexicalNode
) {
(['getType', 'clone'] as const).forEach(method => {
if (!hasOwnStaticMethod(klass, method)) {
console.warn(`${name} must implement static "${method}" method`);
}
});
if (!hasOwnStaticMethod(klass, 'importJSON')) {
console.warn(
`${name} should implement "importJSON" method to ensure JSON and default HTML serialization works as expected`,
);
}
}
}
const type = klass.getType();
const transforms = getTransformSetFromKlass(klass);
registeredNodes.set(type, {
exportDOM: html && html.export ? html.export.get(klass) : undefined,
klass,
replace,
replaceWithKlass,
sharedNodeState: createSharedNodeState(nodes[i]),
transforms,View on GitHub (pinned to 76a22dcba9)
Solutions
- Add `static getType(): string` returning a unique type string to the node class.
- Add `static clone(node): SameNode` returning a new instance cloned from `node`.
- Ensure the class is registered in the editor's nodes array only once and truly extends LexicalNode.
- If this is a mock in tests, define the statics explicitly instead of relying on the base class.
Example fix
// before
class MyNode extends TextNode {}
// after
class MyNode extends TextNode {
static getType(): string {
return 'my-node';
}
static clone(node: MyNode): MyNode {
return new MyNode(node.__text, node.__key);
}
} Defensive patterns
Strategy: type-guard
Validate before calling
function assertNodeStatics(klass: any) {
for (const m of ['getType', 'clone']) {
if (!Object.prototype.hasOwnProperty.call(klass, m)) {
throw new Error(`${klass.name} must implement static "${m}"`);
}
}
} Type guard
function hasOwnStaticMethod(klass: Function, method: string): boolean {
return Object.prototype.hasOwnProperty.call(klass, method) && typeof (klass as any)[method] === 'function';
} Prevention
- Always define static getType and static clone on every custom node class — never rely on inheritance.
- Add a unit test that iterates your nodes array and asserts hasOwnStaticMethod for getType/clone.
- Prefer the $create factory + class template from the docs when creating new nodes.
When it happens
Trigger: Passing a custom node class in createEditor({nodes: [...]}) (or nestedEditor node arrays) that extends a Lexical node but does not declare `static getType()` or `static clone()` itself — e.g. a mock or a class relying on inheritance.
Common situations: Hand-rolled CustomNode extending TextNode/ElementNode with only instance methods; test mocks subclassing LexicalNode; classes compiled/transpiled in a way that drops statics; older node definitions predating the clone() requirement.
Related errors
- ${name} should implement "importJSON" method to ensure JSON
- [lexical] duplicate DOMImportRule name "${rule.name}" — keep
- message
- TableNode: hasHorizontalScroll is active but theme.tableScro
- When using "display: flex" or "display: inline-flex" on an e
AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31).
Data as JSON: /api/errors/398171ee019a5cf8.
Report an issue: GitHub.