Transaction to change a node's attrs --> Error: Invalid content for node doc


I’ve tweaked several things elsewhere in the same timeframe, but I’m pretty sure my issue here just came down to the fact that I was using an arrow function in the nodeViews object.

Any idea what I’m doing wrong here?

Part of an event handler in a nodeView class:

const height = 'some px value';
const tr =;
tr.setNodeMarkup(this.getPos(), null, { height });

schema section:

resizable: {
  attrs: { height: { default: 'auto' }, width: { default: 'auto' } },
  content: 'block*',
  draggable: true,
  parseDOM: [
      getAttrs: dom => ({ height:, width: }),
      tag: 'resizable'
  selectable: false,
  toDOM: node => {
    const { height, width } = node.attrs;
    return ['resizable', { style: `height: ${height}; width: ${width};` }, 0];

My test case is doc with this node and a simple paragraph inside. I still got this error when grabbing the pos via this.view.state.doc.descendants.

Are you sure the initial document is valid, and the pos points at an instance of resizable? I can’t really think of a way updating a node’s markup would be able to raise that error.

edit: Got a bit mixed up in my testing. state.doc.nodeAt(getPos) does give me the correct node. Apologies for the confusion.

My test doc looks like this:

doc: { content: {
  config: { height: '300px' },
  content: [{
    content: [{ text: 'Add a label', type: 'text' }], type: 'paragraph' }],
    type: 'resizable'
  type: 'doc'

My understanding is that pos here would be relative to EditorState.doc. The return value of getPos() is 0, which seems correct to me.

In case it matters, here is the paragraph schema:

paragraph: {
  attrs: { align: { default: 'left' } },
  content: 'inline*',
  group: 'block',
  parseDOM: [
      tag: 'p',
      getAttrs: dom => ({ align: || 'left' })
  toDOM: node => {
    const { align } = node.attrs;
    return ['p', { style: `text-align: ${align}` }, 0];