{"record":{"id":"5d8bf9e8696c7fff","repo":"facebook/lexical","slug":"name-should-implement-importjson-method-to-en","errorCode":null,"errorMessage":"${name} should implement \"importJSON\" method to ensure JSON and default HTML serialization works as expected","messagePattern":"(.+?) should implement \"importJSON\" method to ensure JSON and default HTML serialization works as expected","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/lexical/src/LexicalEditor.ts","lineNumber":1041,"sourceCode":"            `Override for ${name} specifies 'replace' without 'withKlass'. 'withKlass' will be required in a future version.`,\n          );\n        }\n        if (\n          name !== 'RootNode' &&\n          nodeType !== 'root' &&\n          nodeType !== 'artificial' &&\n          // This is mostly for the unit test suite which\n          // uses LexicalNode in an otherwise incorrect way\n          // by mocking its static getType\n          klass !== LexicalNode\n        ) {\n          (['getType', 'clone'] as const).forEach(method => {\n            if (!hasOwnStaticMethod(klass, method)) {\n              console.warn(`${name} must implement static \"${method}\" method`);\n            }\n          });\n          if (!hasOwnStaticMethod(klass, 'importJSON')) {\n            console.warn(\n              `${name} should implement \"importJSON\" method to ensure JSON and default HTML serialization works as expected`,\n            );\n          }\n        }\n      }\n      const type = klass.getType();\n      const transforms = getTransformSetFromKlass(klass);\n      registeredNodes.set(type, {\n        exportDOM: html && html.export ? html.export.get(klass) : undefined,\n        klass,\n        replace,\n        replaceWithKlass,\n        sharedNodeState: createSharedNodeState(nodes[i]),\n        transforms,\n      });\n    }\n  }\n  const editor = new LexicalEditor(","sourceCodeStart":1023,"sourceCodeEnd":1059,"githubUrl":"https://github.com/facebook/lexical/blob/76a22dcba981b46119fcec45f935270707e26a57/packages/lexical/src/LexicalEditor.ts#L1023-L1059","documentation":"During createEditor node validation, a registered node class without its own static `importJSON` is warned about. Without importJSON, JSON serialization round-trips (editorState.toJSON → parseEditorState) and default HTML serialization will not restore this node correctly, so Lexical warns to keep serialization working as expected.","triggerScenarios":"Registering a custom node class via createEditor({nodes: [...]}) (or a nested editor) that lacks a static importJSON method; triggered right after the getType/clone checks for each node class.","commonSituations":"Custom nodes created before importJSON became expected; nodes only ever created programmatically and never deserialized, then later persisted; copy-pasted node templates missing importJSON.","solutions":["Add `static importJSON(json: SerializedNode): ThisNode` that constructs the node via $create factory and calls node.updateFromJSON(json) (or applies each field).","If serialization is irrelevant for this node, still provide a minimal importJSON for safety.","Pair it with exportJSON to guarantee a complete round trip."],"exampleFix":"// before\nclass MyNode extends TextNode {\n  static getType() { return 'my-node'; }\n  static clone(node: MyNode) { return new MyNode(node.__text, node.__key); }\n}\n// after\nclass MyNode extends TextNode {\n  static getType() { return 'my-node'; }\n  static clone(node: MyNode) { return new MyNode(node.__text, node.__key); }\n  static importJSON(json: SerializedMyNode): MyNode {\n    return $createMyNode(json.text).updateFromJSON(json);\n  }\n}","handlingStrategy":"type-guard","validationCode":"if (!Object.prototype.hasOwnProperty.call(MyNode, 'importJSON')) {\n  throw new Error('MyNode must implement static importJSON for serialization');\n}","typeGuard":"function hasImportJSON(klass: any): klass is {importJSON(json: any): any} {\n  return Object.prototype.hasOwnProperty.call(klass, 'importJSON') && typeof klass.importJSON === 'function';\n}","tryCatchPattern":null,"preventionTips":["Implement static importJSON (and exportJSON) on every custom node, even if serialization seems unlikely.","Round-trip test every node type: createEditorState -> toJSON -> parseEditorState and assert equality.","Update node templates when upgrading Lexical as serialization expectations evolve."],"tags":["console-warning","serialization","node-definition","json"],"backgroundTag":"missing-required-method","analyzedSha":"76a22dcba981b46119fcec45f935270707e26a57","analyzedAt":"2026-08-31T21:45:54.792Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}