Skip to content

fix(core): don't throw when the placeholder style is already removed - #3145

Merged
matthewlipski merged 1 commit into
TypeCellOS:mainfrom
adarshsm:fix/3144-placeholder-destroy
Oct 2, 2026
Merged

matthewlipski merged 1 commit into
TypeCellOS:mainfrom
adarshsm:fix/3144-placeholder-destroy

Conversation

@adarshsm

@adarshsm adarshsm commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #3144. Destroying an editor throws NotFoundError: Failed to execute 'removeChild' on 'Node' when the Placeholder extension's <style> element was already removed from <head> (or the shadow root) by something else, e.g. Hotwire Turbo merging the next page's <head> and dropping duplicate empty <style> elements.

Rationale

The Placeholder plugin view's destroy called view.root.removeChild(styleEl) / view.root.head.removeChild(styleEl), which throws if the element is no longer a child. Because it throws inside ProseMirror's EditorView.destroyPluginViews, the rest of that editor's teardown (remaining plugin views, the doc view) is skipped too.

Changes

  • packages/core/src/extensions/Placeholder/Placeholder.ts: use styleEl.remove() in destroy. It removes the element from whatever parent it has (document head or shadow root) and is a no-op if it has none, so both branches collapse into one.

Impact

No behaviour change when the style element is still attached. When it was already detached, unmounting no longer throws and the editor tears down fully.

Testing

  • New packages/core/src/extensions/Placeholder/Placeholder.test.ts: mounts an editor, removes its placeholder <style> from <head>, and checks that editor.unmount() doesn't throw.
  • Verified it fails on main (DOMException NotFoundError thrown) and passes with the fix.
  • vp test --run src/extensions/Placeholder src/editor/BlockNoteEditor.test.ts src/comments in packages/core passes (3 files / 18 tests). vp lint and vp fmt are clean on the changed files.
  • I couldn't run the Docker browser suite on this machine.

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the new feature have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature (n/a)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved placeholder stylesheet cleanup to prevent errors when an editor is unmounted after the stylesheet has been removed.

The Placeholder plugin view removed its <style> on destroy with
removeChild, which throws NotFoundError if something else (e.g. Turbo
merging <head> and dropping duplicate empty <style> elements) detached
it first. The throw also aborts the rest of ProseMirror's view teardown.

Use styleEl.remove(), which is a no-op when the element has no parent
and covers both the document and shadow root cases.

Closes TypeCellOS#3144
@vercel

vercel Bot commented Oct 2, 2026

Copy link
Copy Markdown

@adarshsm is attempting to deploy a commit to the TypeCell Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 9f5ab474-8986-487f-b927-8d9e7c185ce9

📥 Commits

Reviewing files that changed from the base of the PR and between f64d544 and dc9b9da.

📒 Files selected for processing (2)
  • packages/core/src/extensions/Placeholder/Placeholder.test.ts
  • packages/core/src/extensions/Placeholder/Placeholder.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The Placeholder view now removes its style element with styleEl.remove(). A regression test removes the style element before editor unmount and checks that unmount does not throw.

Changes

Placeholder cleanup

Layer / File(s) Summary
Style cleanup and regression test
packages/core/src/extensions/Placeholder/Placeholder.ts, packages/core/src/extensions/Placeholder/Placeholder.test.ts
The destroy callback uses styleEl.remove() instead of separate Shadow DOM and document-root removal calls. The test removes the placeholder stylesheet before unmount and asserts that unmount does not throw.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to dc9b9

The change makes editor teardown tolerate an already-removed placeholder stylesheet, with a regression test for that case. No merge-blocking risk is evident in the supplied context.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: preventing teardown errors when the placeholder style element was already removed.
Description check ✅ Passed The description includes all required sections, explains the issue and rationale, lists the code and test changes, documents impact and testing, and records the checklist status. Screenshots are not a…
Linked Issues check ✅ Passed Issue #3144 requires editor destruction to avoid NotFoundError when the Placeholder <style> element was detached. Placeholder.ts now calls styleEl.remove(), which is a no-op when the element h…
Out of Scope Changes check ✅ Passed The pull request changes only Placeholder style cleanup and adds a regression test for issue #3144. Both changes directly support the linked issue. No unrelated changes are shown.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit watched the style tag go,
Then saw remove() let teardown flow.
The editor unmounted without a throw,
No missing-node complaint below.
The rabbit hopped away, ears aglow.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@3145

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@3145

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@3145

@blocknote/diagram-block

npm i https://pkg.pr.new/@blocknote/diagram-block@3145

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@3145

@blocknote/math-block

npm i https://pkg.pr.new/@blocknote/math-block@3145

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@3145

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@3145

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@3145

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@3145

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@3145

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@3145

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@3145

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@3145

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@3145

@blocknote/xl-typst-exporter

npm i https://pkg.pr.new/@blocknote/xl-typst-exporter@3145

commit: dc9b9da

@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
blocknote Ready Ready Preview Oct 2, 2026 1:26pm UTC
blocknote-website Ready Ready Preview Oct 2, 2026 1:26pm UTC

Request Review

@matthewlipski

Copy link
Copy Markdown
Collaborator

Thanks!

@matthewlipski
matthewlipski merged commit c6f14b0 into TypeCellOS:main Oct 2, 2026
43 of 47 checks passed

This branch was successfully deployed

2 active deployments
Preview – blocknote-website — dc9b9dab Deployed Oct 2, 2026 by vercel[bot]
Preview – blocknote — dc9b9dab Deployed Oct 2, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Placeholder: destroying the editor throws NotFoundError when its <style> was already removed from the head

2 participants