Cannot Remove Widget Decoration

I add widget decorations on the fly using this plugin:

var newDecorations = []
var removeDecorations = []

var decoPlugin = new pmState.Plugin({
    state: {
    init(_, {doc}) {
      return pmView.DecorationSet.create(doc, newDecorations)
    apply(tr, set) {
      var newSet =, tr.doc, {
        onRemove: function(decoSpec) {
          var domNode = makeDecoDOM(decoSpec.type)
          newDecorations.push(pmView.Decoration.widget(decoSpec.pos, domNode, decoSpec))
      }).add(tr.doc, newDecorations).remove(removeDecorations)
      newDecorations = []
      removeDecorations = []
      return newSet
    props: {
    decorations(state) { return decoPlugin.getState(state) }

… and during my dispatchTransaction:

   removeDecorations = decoPlugin.props.decorations(view.state).find(start, end)

My removeDecorations array gets filled but no decorations are removed.

Am I using this correctly?

I can post reproducible code later when needed.

I don’t see what might be going wrong, but using global mutable arrays to communicate with state apply methods is a bad idea. If you can derive which decorations should be removed from the transaction (which you typically can), you should do that in the apply method, not when dispatching.

Possibly related, immediately re-adding decorations that are removed by mapping seems extremely suspicious. What is the intention there?

Thanks for help and coding tips. I will try it out.

I am using ProseMirror for an editor with “inline comments”. These comments, I not only want to wrap in a node, but also add uneditable text as widgets at start and end, to always have a serialized representation of the commented text available when I retrieve the textContent of the editor element. This is what I save in my database and also present to users through the widget decorations.

When text is removed at the position of the widgets they are also removed by ProseMirror, but I usually want to keep them because my comments are usually still there.

With usually being the problematic part, right? I think a node view would be a better fit for this use case.

Wow, thanks, NodeViews look more fitting indeed.