{"record":{"id":"80eff96258c6d0f7","repo":"BookStackApp/BookStack","slug":"no-root-element","errorCode":null,"errorMessage":"No root element.","messagePattern":"No root element\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"resources/js/wysiwyg/lexical/table/LexicalTableSelectionHelpers.ts","lineNumber":97,"sourceCode":"export const getDOMSelection = (\n  targetWindow: Window | null,\n): Selection | null =>\n  CAN_USE_DOM ? (targetWindow || window).getSelection() : null;\n\nconst isMouseDownOnEvent = (event: MouseEvent) => {\n  return (event.buttons & 1) === 1;\n};\n\nexport function applyTableHandlers(\n  tableNode: TableNode,\n  tableElement: HTMLTableElementWithWithTableSelectionState,\n  editor: LexicalEditor,\n  hasTabHandler: boolean,\n): TableObserver {\n  const rootElement = editor.getRootElement();\n\n  if (rootElement === null) {\n    throw new Error('No root element.');\n  }\n\n  const tableObserver = new TableObserver(editor, tableNode.getKey());\n  const editorWindow = editor._window || window;\n\n  attachTableObserverToTableElement(tableElement, tableObserver);\n\n  const createMouseHandlers = () => {\n    const onMouseUp = () => {\n      tableObserver.isSelecting = false;\n      editorWindow.removeEventListener('mouseup', onMouseUp);\n      editorWindow.removeEventListener('mousemove', onMouseMove);\n    };\n\n    const onMouseMove = (moveEvent: MouseEvent) => {\n      // delaying mousemove handler to allow selectionchange handler from LexicalEvents.ts to be executed first\n      setTimeout(() => {\n        if (!isMouseDownOnEvent(moveEvent) && tableObserver.isSelecting) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/resources/js/wysiwyg/lexical/table/LexicalTableSelectionHelpers.ts#L79-L115","documentation":"Internal sanity guard in Lexical's applyTableHandlers: the editor's root DOM element (editor.getRootElement()) is null when table selection handlers are being attached, meaning the table registration ran against an editor that is not yet (or no longer) attached to a DOM element.","triggerScenarios":"Thrown at resources/js/wysiwyg/lexical/table/LexicalTableSelectionHelpers.ts:97 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure applyTableHandlers/tableSelection is only called after the editor is mounted with a root element","Check the editor has not been torn down before the table plugin initializes","Verify the editor container element exists in the DOM at plugin setup time"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}