{"record":{"id":"a14fd900dae7c349","repo":"facebook/lexical","slug":"createtextnodesfromytext-node-type-is-not-reg","errorCode":null,"errorMessage":"$createTextNodesFromYText: Node ${type} is not registered","messagePattern":"\\$createTextNodesFromYText: Node (.+?) is not registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/lexical-yjs/src/SyncV2.ts","lineNumber":398,"sourceCode":"): TextNode[] | null => {\n  const deltas = toDelta(text, snapshot, prevSnapshot, computeYChange);\n\n  // Use existing text nodes if the count and types all align, otherwise throw out the existing\n  // nodes and create new ones.\n  let nodes: TextNode[] = binding.mapping.get(text) ?? [];\n\n  const nodeTypes: string[] = deltas.map(\n    delta => delta.attributes.t ?? TextNode.getType(),\n  );\n  const canReuseNodes =\n    nodes.length === nodeTypes.length &&\n    nodes.every((node, i) => node.getType() === nodeTypes[i]);\n  if (!canReuseNodes) {\n    const registeredNodes = binding.editor._nodes;\n    nodes = nodeTypes.map(type => {\n      const nodeInfo = registeredNodes.get(type);\n      if (nodeInfo === undefined) {\n        throw new Error(\n          `$createTextNodesFromYText: Node ${type} is not registered`,\n        );\n      }\n      const node = new nodeInfo.klass();\n      if (!$isTextNode(node)) {\n        throw new Error(\n          `$createTextNodesFromYText: Node ${type} is not a TextNode`,\n        );\n      }\n      return node;\n    });\n  }\n\n  // Sync text, properties and state to the text nodes.\n  for (let i = 0; i < deltas.length; i++) {\n    const node = nodes[i];\n    const delta = deltas[i];\n    const {attributes, insert} = delta;","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/facebook/lexical/blob/76a22dcba981b46119fcec45f935270707e26a57/packages/lexical-yjs/src/SyncV2.ts#L380-L416","documentation":"During Yjs→Lexical sync (SyncV2), a Y.Text node's stored node type string is looked up in the editor's registered node map (editor._nodes). If no class is registered under that type, Lexical cannot instantiate the corresponding LexicalNode and throws instead of silently dropping data. This guarantees collaborative content never disappears due to a missing registration.","triggerScenarios":"$createOrUpdateTextNodesFromYText reads a Y.Text (or nested Y type) whose type attribute names a node type not present in binding.editor._nodes — i.e. the editor was built without that node in its nodes: config.","commonSituations":"Collab document created in an app that registers custom text nodes (e.g. hashtag or mention nodes) is opened by a client whose editor config omits those nodes; adding a new custom node type on one client and failing to register it on others; reusing a plain-text editor config with a rich-text Yjs doc.","solutions":["Register every node type that can appear in the shared Yjs document: add the class to the editor's nodes config / extension nodes: array.","Verify the exact missing type from the error message and ensure both ends of the collaboration use the same package/version that defines it.","If the type is a built-in (e.g. 'text', 'hashtag'), import and register the corresponding package's nodes.","For schema-drift between clients, gate sync or render a placeholder node while the type is unavailable."],"exampleFix":"// before\nconst initialConfig = { nodes: [RootNode, ParagraphNode] };\n// after\nconst initialConfig = { nodes: [RootNode, ParagraphNode, TextNode, HashtagNode] };","handlingStrategy":"validation","validationCode":"const type = /* type from Y.Text */;\nconst registered = editor._nodes.get(type);\nif (!registered) {\n  throw new Error(`Editor missing registration for Yjs node type: ${type}`);\n}","typeGuard":"function isNodeTypeRegistered(editor: LexicalEditor, type: string): boolean {\n  return editor._nodes.has(type);\n}","tryCatchPattern":"try {\n  syncYTextToLexical(binding, yText);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('is not registered')) {\n    console.error('Collab schema mismatch: register missing node type', e.message);\n  } else { throw e; }\n}","preventionTips":["Register every custom node in the editor config on all collaborating clients.","Share a single nodes list module imported by every entry point.","Add a startup assertion that all schema-declared node types are registered.","Keep Lexical package versions aligned across clients."],"tags":["yjs","collaboration","node-registration","configuration"],"backgroundTag":"unregistered-node-type","analyzedSha":"76a22dcba981b46119fcec45f935270707e26a57","analyzedAt":"2026-08-31T21:45:54.792Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}