{"record":{"id":"356184294b289327","repo":"ianstormtaylor/slate","slug":"cannot-set-properties-on-the-root-node","errorCode":null,"errorMessage":"Cannot set properties on the root node!","messagePattern":"Cannot set properties on the root node!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/slate/src/interfaces/transforms/general.ts","lineNumber":248,"sourceCode":"        modifyLeaf(editor, path, node => {\n          const before = node.text.slice(0, offset)\n          const after = node.text.slice(offset + text.length)\n\n          return {\n            ...node,\n            text: before + after,\n          }\n        })\n\n        transformSelection = true\n        break\n      }\n\n      case 'set_node': {\n        const { path, properties, newProperties } = op\n\n        if (path.length === 0) {\n          throw new Error(`Cannot set properties on the root node!`)\n        }\n\n        modifyDescendant(editor, path, node => {\n          const newNode = { ...node }\n\n          for (const key in newProperties) {\n            if (NON_SETTABLE_NODE_PROPERTIES.includes(key)) {\n              throw new Error(`Cannot set the \"${key}\" property of nodes!`)\n            }\n\n            const value = newProperties[<keyof Node>key]\n\n            // Make sure we're not setting `then` to a function, since this will\n            // cause the node to be treated as a Promise-like object, which can\n            // cause unexpected behaviour when returning the node from async\n            // functions.\n            if (key === 'then' && typeof value === 'function') {\n              throw new Error(","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/ianstormtaylor/slate/blob/72a37c701e5da4bb13a305d416d9c070d19d3a45/packages/slate/src/interfaces/transforms/general.ts#L230-L266","documentation":"A set_node operation sets properties on a node. The root node is the top-level Editor object, not a regular Node, so Slate throws when set_node is applied with path [].","triggerScenarios":"Applying { type: 'set_node', path: [], ... } or calling Transforms.setNodes(editor, props, { at: [] }); also when a computed path collapses to [] after transforms.","commonSituations":"Calling Transforms.setNodes with at pointing at the whole editor instead of a specific element; selections/paths resolving to the root after deletions; custom normalizers setting properties on editor by path.","solutions":["Target a concrete element instead: use at: [0] or the current selection, or set properties directly on the editor object (editor.prop = value).","Guard: if (path.length === 0) skip or handle specially before applying set_node.","If using Editor.withNormalization custom code, make sure paths passed to setNodes never degrade to []."],"exampleFix":"// before\nTransforms.setNodes(editor, { align: 'center' }, { at: [] })\n\n// after\nTransforms.setNodes(editor, { align: 'center' }, { at: [0] })\n// or set a root-level (editor) property directly:\n// editor.someProp = value","handlingStrategy":"validation","validationCode":"if (path.length > 0) {\n  Transforms.setNodes(editor, props, { at: path })\n} else {\n  Object.assign(editor, props) // root-level properties set directly\n}","typeGuard":"function isDescendantPath(path: Path): boolean {\n  return path.length > 0\n}","tryCatchPattern":null,"preventionTips":["Never pass at: [] to Transforms.setNodes.","Set editor-level state by direct assignment, not via operations.","Check resolved paths after destructive transforms before setting nodes."],"tags":["slate","set-node","root-node","operation"],"backgroundTag":"operation-apply-failed","analyzedSha":"72a37c701e5da4bb13a305d416d9c070d19d3a45","analyzedAt":"2026-08-27T23:04:51.145Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}