fix(summary): prevent BlockNote rendering crashes with patch + boundary#470
Open
passabilities wants to merge 3 commits into
Open
fix(summary): prevent BlockNote rendering crashes with patch + boundary#470passabilities wants to merge 3 commits into
passabilities wants to merge 3 commits into
Conversation
The summary view occasionally hits render-phase failures (e.g. BlockNote choking on otherwise-valid block input). Without a boundary, any such failure takes down the entire meeting page with Next.js's generic "Application error: a client-side exception has occurred" overlay. Add a class-based error boundary that: - catches render-phase errors via `getDerivedStateFromError` / `componentDidCatch`, - shows the raw markdown in a readable fallback so the user retains access to the summary content, - exposes an optional 'Regenerate' button wired through to `onRegenerateSummary`. The boundary is consumed by `BlockNoteSummaryView` in the next commit.
… specs
prosemirror-view 1.41 unconditionally pipes the result of
`node.type.spec.toDOM(node)` (and the mark equivalent) through
`DOMSerializer.renderSpec` inside `NodeViewDesc.create` /
`MarkViewDesc.create`. `renderSpec` only knows how to handle:
- text DOM nodes,
- `{dom: <textNode>}` objects, and
- array specs `["tag", attrs?, ...children]`.
It does NOT handle `{dom: <element>, contentDOM?}`, which is one of
the documented valid `DOMOutputSpec` shapes — and the one BlockNote's
`renderHTML` returns for every block (via `createDefaultBlockDOMOutputSpec`
and similar helpers). The result is `RangeError: Invalid array passed
to renderSpec` thrown on every BlockNote editor mount, taking down
the whole meeting page.
Patch `prosemirror-view`'s `dist/index.js` and `dist/index.cjs` via
pnpm patch: before calling `renderSpec`, check whether the toDOM
result already has a `.dom` property and, if so, use it directly.
This preserves the array-spec path unchanged.
Register the patch in `pnpm-workspace.yaml` under `patchedDependencies`
so subsequent `pnpm install` runs apply it automatically.
…oundary Two small touches to `BlockNoteSummaryView`: 1. Disable the `placeholder` extension on the BlockNote editor. With the plugin enabled, BlockNote 0.36 produces a `DecorationSource` that's missing the `localsInner` method ProseMirror 1.41 calls in `DecorationGroup.locals()` — the editor crashes on every mount with `TypeError: undefined is not an object (evaluating 'this.members[i].localsInner')`. Bisected against the disable list; `placeholder` is the sole culprit. Other plugins (sideMenu, suggestionMenus, formattingToolbar, linkToolbar, filePanel, tableHandles, animations, etc.) work fine. 2. Wrap both render branches (`blocknote` for saved `summary_json`, `markdown` for fresh LLM output) in `SummaryErrorBoundary` so any future render-phase failure falls back to readable raw markdown instead of crashing the page.
Collaborator
|
@safvanatzack please address |
Collaborator
|
@passabilities Thanks for the contribution I think the ProseMirror patch/placeholder workaround here is mostly superseded by #472, which pins the BlockNote ProseMirror stack and aliases ProseMirror packages to single instances. The useful follow-up from this PR may be the Thank you |
bobby-claw
pushed a commit
to NERV-es/meetily
that referenced
this pull request
Jun 1, 2026
…ackriya-Solutions#457 Zackriya-Solutions#430 Zackriya-Solutions#470 Zackriya-Solutions#420 Ported from upstream Zackriya-Solutions/meetily: - Zackriya-Solutions#475: Whisper vocabulary hints (meeting domain support) - Zackriya-Solutions#478: Export transcripts as TXT/VTT with file-save dialog - Zackriya-Solutions#457: Integration API via deep-link URL scheme + distributed notifications - Zackriya-Solutions#430: Apple Speech engine (cfg-gated behind 'apple-speech' feature) - Zackriya-Solutions#470: BlockNote v0.16 editor upgrade - Zackriya-Solutions#420: Monochrome tray icon (proper macOS template image) Apple Speech engine gated behind feature flag due to upstream Send/Sync issues with objc2 types — enable with: cargo build --features apple-speech
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The summary editor crashes for some meetings with a
Cannot read properties of undefined (reading 'localsInner')ordom is undefinederror originating in prosemirror-view, taking down the entire meeting page. This PR adds three independent layers of defense:Patch
prosemirror-viewto honor{dom, contentDOM}toDOM specs. BlockNote 0.36's node specs sometimes return a{dom, contentDOM}shape fromtoDOM, but upstream prosemirror-view unconditionally forwards the result toDOMSerializer.renderSpec, which throws when given that shape. The patch checks for the shape and uses it directly when present.Disable BlockNote's
placeholderplugin. BlockNote 0.36's placeholder plugin produces aDecorationSourcethat's missinglocalsInner, which crashesDecorationGroup.locals()in prosemirror-view during the initial editor mount. We have no UX dependency on the placeholder, so disabling it is the cleanest fix.Wrap the editor in
SummaryErrorBoundary. Even with (1) and (2), any future regression in the editor stack would otherwise take down the whole page. The boundary catches render failures and shows a fallback with the raw markdown plus a retry button, so a single bad summary can't break navigation.Files
frontend/patches/prosemirror-view@1.41.8.patch— new pnpm patch (also patchesdist/index.cjsanddist/index.js)frontend/pnpm-workspace.yaml— registers the patch viapatchedDependenciesfrontend/src/components/AISummary/BlockNoteSummaryView.tsx—disableExtensions: ['placeholder']and wraps both render paths in the boundaryfrontend/src/components/AISummary/SummaryErrorBoundary.tsx— new class component with fallback UIType of Change
Testing
Editorto confirm the boundary catches and the rest of the UI stays interactive.Checklist