Schema not enforced on node creation

Hi

So recently I made a change to my schema but forgot to update some node creation logic. What was an obvious bug became a lot more excruciating to detect as apparently ProseMirror allows creation of nodes with invalid schema. I noticed it by doing an unrelated tr.setNodeMarkup(... which just threw a generic invalid content error leaving me wondering if I had duplicate ProseMirror libraries or something.

Here’s reproduction React App

Schema https://github.com/TeemuKoivisto/prosemirror-schema-not-enforced-bug/blob/master/example/src/pm/schema.ts

Command https://github.com/TeemuKoivisto/prosemirror-schema-not-enforced-bug/blob/master/example/src/components/editor/RightPanel.tsx#L9

This is intentional—when creating a Slice, the outer nodes may not be complete, and recursively checking content on node creation would generally be rather expensive. There’s a check method to explicitly test a node’s schema conformance.

Oh I see. So one should use createChecked instead. In general though these performance hits would be small when you operate on only a few nodes?

I’m just thinking what would be a reasonable prevention for doing something like this in the future. Always use createChecked for the root node would be a good rule of thumb but I wonder how to enforce it. Hmm adding a state.doc.check() when you load the document will at least crash it appropriately.

On second thought this does seem like a gargantuan footgun. Once you let an incorrect node pass through your document is now inconsistent and there’s no way of recovering afterwards. To fix it you have to add a manual transformation when the doc is loaded checking each node with hacky doc.descendants check. Or you run some script for all the docs in your DB which should update all clients’ live docs as well.

2 Likes