{"record":{"id":"b40e1283897ecfa4","repo":"facebook/lexical","slug":"hashtagplugin-hashtagnode-not-registered-on-edito","errorCode":null,"errorMessage":"HashtagPlugin: HashtagNode not registered on editor","messagePattern":"HashtagPlugin: HashtagNode not registered on editor","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/lexical-react/src/LexicalHashtagPlugin.ts","lineNumber":28,"sourceCode":"import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';\nimport {type JSX, useEffect} from 'react';\n\n/**\n * Enables hashtag support by transforming runs of text that begin with `#`\n * into {@link HashtagNode}s. The editor must have the {@link HashtagNode}\n * registered.\n *\n * This is a legacy plugin. When building an editor with the extension API,\n * configure {@link HashtagExtension} instead.\n *\n * @returns `null`, this plugin renders no DOM of its own.\n */\nexport function HashtagPlugin(): JSX.Element | null {\n  const [editor] = useLexicalComposerContext();\n\n  useEffect(() => {\n    if (!editor.hasNodes([HashtagNode])) {\n      throw new Error('HashtagPlugin: HashtagNode not registered on editor');\n    }\n    return registerLexicalHashtag(editor);\n  }, [editor]);\n\n  return null;\n}\n","sourceCodeStart":10,"sourceCodeEnd":35,"githubUrl":"https://github.com/facebook/lexical/blob/76a22dcba981b46119fcec45f935270707e26a57/packages/lexical-react/src/LexicalHashtagPlugin.ts#L10-L35","documentation":"HashtagPlugin decorates hashtag text, which only works if the editor knows the HashtagNode class; Lexical editors can only process node types listed in their nodes config. The plugin checks editor.hasNodes([HashtagNode]) inside a useEffect and throws immediately if it is missing. This catches the configuration mistake at mount time instead of failing when a hashtag is typed.","triggerScenarios":"Rendering <HashtagPlugin /> inside a LexicalComposer whose editor was created without HashtagNode in its nodes array.","commonSituations":"Building a custom editor configuration by hand and forgetting @lexical/hashtag's node; adding the plugin copied from the playground to an app with a minimal nodes list; switching from a preset (e.g. rich text extension bundle) to explicit node registration.","solutions":["Add HashtagNode (from @lexical/hashtag) to the editor's nodes array","Use the hashtag extension via buildEditorFromExtensions so the node is registered","Guard rendering: only mount HashtagPlugin when editor.hasNodes([HashtagNode]) is true"],"exampleFix":"// before\nconst initialConfig = {nodes: [ParagraphNode, TextNode]};\n<LexicalComposer initialConfig={initialConfig}><HashtagPlugin /></LexicalComposer> // throws\n\n// after\nimport {HashtagNode} from '@lexical/hashtag';\nconst initialConfig = {nodes: [ParagraphNode, TextNode, HashtagNode]};\n<LexicalComposer initialConfig={initialConfig}><HashtagPlugin /></LexicalComposer> // ok","handlingStrategy":"validation","validationCode":"import {HashtagNode} from '@lexical/hashtag';\nif (!editor.hasNodes([HashtagNode])) {\n  throw new Error('Add HashtagNode to your editor nodes config before using HashtagPlugin');\n}","typeGuard":"function supportsHashtags(editor: LexicalEditor): boolean {\n  return editor.hasNodes([HashtagNode]);\n}","tryCatchPattern":"try {\n  if (!editor.hasNodes([HashtagNode])) throw new Error('HashtagNode missing');\n  // render/use plugin\n} catch (e) {\n  console.error('HashtagPlugin misconfigured:', e);\n}","preventionTips":["Render plugins conditionally only after node registration is confirmed","List all decorator/transform node classes in initialConfig.nodes","Run editor.hasNodes checks in dev-mode editor factory"],"tags":["lexical","react","node-registration","plugin"],"backgroundTag":"missing-node-registration","analyzedSha":"76a22dcba981b46119fcec45f935270707e26a57","analyzedAt":"2026-08-31T21:45:54.792Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}