You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Placeholder: destroying the editor throws NotFoundError when its <style> was already removed from the head #3144
The Placeholder extension appends an empty <style> element to view.root.head for every editor (its rules go in through sheet.insertRule), and its plugin view removes it on destroy with removeChild:
If anything removed that <style> first, removeChild throws:
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
Because the throw happens inside ProseMirror's EditorView.destroyPluginViews, it also aborts the rest of that editor's teardown: the plugin views still on the stack and the doc view are never destroyed.
We hit it with Hotwire Turbo. On a page visit, Turbo merges the new <head> into the current one and drops all but the first of elements with identical outerHTML. Every Placeholder <style> is <style></style>, so with several editors on a page — in our case the comment editors of the threads sidebar — all but one lose their style before the editors unmount, and each of those teardowns throws. Stack from production (React 19.2.4):
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
at Object.destroy (Placeholder)
at EditorView.destroyPluginViews
at EditorView.destroy
at Editor.unmount
at BlockNoteEditor.unmount
at safelyDetachRef
at commitDeletionEffectsOnFiber
What did you expect to happen?
Destroying the editor should not throw when its <style> is already gone. styleEl.remove() does the same thing and is a no-op when the element has no parent, so it covers both branches:
Destroy the editor (unmount the component, or editor._tiptapEditor.destroy()).
NotFoundError is thrown from the Placeholder plugin view's destroy.
BlockNote version
0.53.0 (the code is unchanged on main / 0.55.0)
Environment
Chrome 151 and Electron (Cypress), React 19.2.4, Hotwire Turbo 8.0.23
Additional context
Our workaround, until this is fixed: a MutationObserver on document.head gives each Placeholder <style> a distinct attribute, so Turbo no longer treats them as duplicates — Grupo-AFAL/bali-view-components#1224. It works, but it only covers one way of losing the element; remove() would cover all of them.
Activity
fix(core): don't throw when the placeholder style is already removed (T…