# uncatchable out of range errors when document changes

**URL:** https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864
**Category:** v6
**Created:** [August 14, 2022, 8:34am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864 "2022-08-14T08:34:57Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![felixroos](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/felixroos/32/2366_2.png) [@felixroos](https://discuss.codemirror.net/u/felixroos)
#### Post date: [August 14, 2022, 8:34am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/1 "2022-08-14T08:34:57Z")

</div>

Hello and thanks for creating this lovely tool!

I am writing a [music live coding editor](https://strudel.tidalcycles.org/) where decoration changes can be dispatched every frame.  
When the document gets shorter, it can happen that changes are fired that still receive the old document state, leading to errors like:

```auto
Position 281 is out of range for changeset of length 180

```

When that error happens, the application crashes and gets into an unusable state. It would be really helpful to be able to catch that error and just ignore it, because it is not critical if a highlight is missed.

I created a minimal reproduction here: [react-codemirror-range-error - CodeSandbox](https://codesandbox.io/s/react-codemirror-range-error-i67cs6?file=/src/App.js) the error will be thrown whenever the document content is deleted all at once.

I assume the problem is that the document changes between the call to view.dispatch and the actual execution, possibly because requestAnimationFrame is not fired synchronously.

Questions:

1. Is there a way to hook into codemirrors requestAnimationFrame loop or a way to always get the latest state of the document?
2. If this is a just a problem with the react component, wouldn’t it still make sense to be able to catch critical errors?

Greetings, Felix

---

<div class="post-metadata">

### Author: ![felixroos](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/felixroos/32/2366_2.png) [@felixroos](https://discuss.codemirror.net/u/felixroos)
#### Post date: [August 14, 2022, 9:07am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/2 "2022-08-14T09:07:12Z")

</div>

It seems I have fixed it [like this](https://codesandbox.io/s/react-codemirror-range-error-forked-gbus5r?file=/src/App.js)… I have to test this with my actual setup to verify that this was the problem…

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/marijn/32/136_2.png) [@marijn](https://discuss.codemirror.net/u/marijn)
#### Post date: [August 14, 2022, 9:10am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/3 "2022-08-14T09:10:40Z")

</div>

`dispatch` happens entirely synchronously. If you can reproduce an issue like this without react and react-codemirror, I’d be interested in debugging that. As it is, I don’t know what magic might be going on inside that React component.

---

<div class="post-metadata">

### Author: ![jaywcjlove](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/jaywcjlove/32/1485_2.png) [@jaywcjlove](https://discuss.codemirror.net/u/jaywcjlove)
#### Post date: [July 1, 2023, 1:07am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/4 "2023-07-01T01:07:41Z")

</div>

I reproduced this error using codemirror, maybe the problem has nothing to do with react.

[https://codemirror.net/try/?c=aW1wb3J0IHtiYXNpY1NldHVwLCBFZGl0b3JWaWV3fSBmcm9tICJjb2RlbWlycm9yIgppbXBvcnQge2phdmFzY3JpcHR9IGZyb20gIkBjb2RlbWlycm9yL2xhbmctamF2YXNjcmlwdCIKaW1wb3J0IHsgU3RhdGVGaWVsZCwgU3RhdGVFZmZlY3QgfSBmcm9tICJAY29kZW1pcnJvci9zdGF0ZSI7CmltcG9ydCB7IERlY29yYXRpb24gfSBmcm9tICJAY29kZW1pcnJvci92aWV3IjsKCmNvbnN0IHNldEhpZ2hsaWdodHMgPSBTdGF0ZUVmZmVjdC5kZWZpbmUoKTsKY29uc3QgaGlnaGxpZ2h0RmllbGQgPSBTdGF0ZUZpZWxkLmRlZmluZSh7CiAgY3JlYXRlKCkgewogICAgcmV0dXJuIERlY29yYXRpb24ubm9uZTsKICB9LAogIHVwZGF0ZShoaWdobGlnaHRzLCB0cikgewogICAgZm9yIChsZXQgZSBvZiB0ci5lZmZlY3RzKSB7CiAgICAgIGNvbnN0IGNoYXIgPSBlLnZhbHVlOwogICAgICBpZiAoZS5pcyhzZXRIaWdobGlnaHRzKSAmJiB0ci5zdGF0ZS5kb2MubGVuZ3RoKSB7CiAgICAgICAgY29uc3QgbWFyayA9IERlY29yYXRpb24ubWFyayh7CiAgICAgICAgICBhdHRyaWJ1dGVzOiB7IHN0eWxlOiBgb3V0bGluZTogMnB4IHNvbGlkIGJsdWVgIH0KICAgICAgICB9KS5yYW5nZShjaGFyLCBjaGFyICsgMSk7CiAgICAgICAgaGlnaGxpZ2h0cyA9IERlY29yYXRpb24uc2V0KFttYXJrXSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBoaWdobGlnaHRzOwogIH0sCiAgcHJvdmlkZTogKGYpID0+IEVkaXRvclZpZXcuZGVjb3JhdGlvbnMuZnJvbShmKQp9KTsKCgp2YXIgdmlldyA9IG5ldyBFZGl0b3JWaWV3KHsKICBkb2M6ICJjb25zb2xlLmxvZygnaGVsbG8nKVxuIiwKICBleHRlbnNpb25zOiBbYmFzaWNTZXR1cCwgamF2YXNjcmlwdCgpLCBoaWdobGlnaHRGaWVsZF0sCiAgcGFyZW50OiBkb2N1bWVudC5ib2R5Cn0pCgoKdmFyIGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZUhpZ2hsaWdodHMpOwpmdW5jdGlvbiB1cGRhdGVIaWdobGlnaHRzKCkgewogIHRyeSB7CiAgICBjb25zdCBjaGFyID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogdmlldy5zdGF0ZS5kb2MubGVuZ3RoIC0gMSk7CiAgICB2aWV3LmRpc3BhdGNoKHsgZWZmZWN0czogc2V0SGlnaGxpZ2h0cy5vZihjaGFyKSB9KTsgLy8gaGlnaGxpZ2h0IGFsbCBzdGlsbCBhY3RpdmUgKyBuZXcgYWN0aXZlIGhhcHMKICAgIGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZUhpZ2hsaWdodHMpOwogIH0gY2F0Y2ggKGVycikgewogICAgLy8gZXZlbiB0aG91Z2ggd2UgY2F0Y2ggZXJyb3JzIGhlcmUsCiAgICAvLyB0aGUgcmFuZ2UgZXJyb3Igc3RpbGwgY3Jhc2hlcwogICAgY29uc29sZS5sb2coImVyciIsIGVycik7CiAgfQp9](https://codemirror.net/try/?c=aW1wb3J0IHtiYXNpY1NldHVwLCBFZGl0b3JWaWV3fSBmcm9tICJjb2RlbWlycm9yIgppbXBvcnQge2phdmFzY3JpcHR9IGZyb20gIkBjb2RlbWlycm9yL2xhbmctamF2YXNjcmlwdCIKaW1wb3J0IHsgU3RhdGVGaWVsZCwgU3RhdGVFZmZlY3QgfSBmcm9tICJAY29kZW1pcnJvci9zdGF0ZSI7CmltcG9ydCB7IERlY29yYXRpb24gfSBmcm9tICJAY29kZW1pcnJvci92aWV3IjsKCmNvbnN0IHNldEhpZ2hsaWdodHMgPSBTdGF0ZUVmZmVjdC5kZWZpbmUoKTsKY29uc3QgaGlnaGxpZ2h0RmllbGQgPSBTdGF0ZUZpZWxkLmRlZmluZSh7CiAgY3JlYXRlKCkgewogICAgcmV0dXJuIERlY29yYXRpb24ubm9uZTsKICB9LAogIHVwZGF0ZShoaWdobGlnaHRzLCB0cikgewogICAgZm9yIChsZXQgZSBvZiB0ci5lZmZlY3RzKSB7CiAgICAgIGNvbnN0IGNoYXIgPSBlLnZhbHVlOwogICAgICBpZiAoZS5pcyhzZXRIaWdobGlnaHRzKSAmJiB0ci5zdGF0ZS5kb2MubGVuZ3RoKSB7CiAgICAgICAgY29uc3QgbWFyayA9IERlY29yYXRpb24ubWFyayh7CiAgICAgICAgICBhdHRyaWJ1dGVzOiB7IHN0eWxlOiBgb3V0bGluZTogMnB4IHNvbGlkIGJsdWVgIH0KICAgICAgICB9KS5yYW5nZShjaGFyLCBjaGFyICsgMSk7CiAgICAgICAgaGlnaGxpZ2h0cyA9IERlY29yYXRpb24uc2V0KFttYXJrXSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBoaWdobGlnaHRzOwogIH0sCiAgcHJvdmlkZTogKGYpID0+IEVkaXRvclZpZXcuZGVjb3JhdGlvbnMuZnJvbShmKQp9KTsKCgp2YXIgdmlldyA9IG5ldyBFZGl0b3JWaWV3KHsKICBkb2M6ICJjb25zb2xlLmxvZygnaGVsbG8nKVxuIiwKICBleHRlbnNpb25zOiBbYmFzaWNTZXR1cCwgamF2YXNjcmlwdCgpLCBoaWdobGlnaHRGaWVsZF0sCiAgcGFyZW50OiBkb2N1bWVudC5ib2R5Cn0pCgoKdmFyIGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZUhpZ2hsaWdodHMpOwpmdW5jdGlvbiB1cGRhdGVIaWdobGlnaHRzKCkgewogIHRyeSB7CiAgICBjb25zdCBjaGFyID0gTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogdmlldy5zdGF0ZS5kb2MubGVuZ3RoIC0gMSk7CiAgICB2aWV3LmRpc3BhdGNoKHsgZWZmZWN0czogc2V0SGlnaGxpZ2h0cy5vZihjaGFyKSB9KTsgLy8gaGlnaGxpZ2h0IGFsbCBzdGlsbCBhY3RpdmUgKyBuZXcgYWN0aXZlIGhhcHMKICAgIGZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHVwZGF0ZUhpZ2hsaWdodHMpOwogIH0gY2F0Y2ggKGVycikgewogICAgLy8gZXZlbiB0aG91Z2ggd2UgY2F0Y2ggZXJyb3JzIGhlcmUsCiAgICAvLyB0aGUgcmFuZ2UgZXJyb3Igc3RpbGwgY3Jhc2hlcwogICAgY29uc29sZS5sb2coImVyciIsIGVycik7CiAgfQp9)

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/marijn/32/136_2.png) [@marijn](https://discuss.codemirror.net/u/marijn)
#### Post date: [July 1, 2023, 8:39am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/5 "2023-07-01T08:39:44Z")

</div>

Your field definition isn’t mapping the decoration set through the transaction’s changes, which will cause it to still have decorations pointing at parts of the document that no longer exist, leading to this error. Add a line like `highlights = highlights.map(tr.changes)` at the top of the `update` function to avoid that.

---

<div class="post-metadata">

### Author: ![jaywcjlove](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/jaywcjlove/32/1485_2.png) [@jaywcjlove](https://discuss.codemirror.net/u/jaywcjlove)
#### Post date: [July 7, 2023, 4:32am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/6 "2023-07-07T04:32:05Z")

</div>

> [@felixroos](#):
>
> thrown whenever the document content is deleted all at once.
> 
> I assume the problem is that the document changes between the call to view.dispatch and the actual execution, possibly because requestAnimationFrame is not fired synchronously.
> 
> Questions:
> 
> 1. Is there a way to hook into codemirrors requestAnimationFrame loop or a way to always get the latest state of the document?
> 2. If this is a just a problem with the react component, wouldn’t it still make sense to be able to catch critical errors?
> 
> Greetings, Felix

It works fine.

```js
import {basicSetup, EditorView} from "codemirror"
import {javascript} from "@codemirror/lang-javascript"
import { StateField, StateEffect } from "@codemirror/state";
import { Decoration } from "@codemirror/view";

const setHighlights = StateEffect.define();
const highlightField = StateField.define({
  create() {
    return Decoration.none;
  },
  update(highlights, tr) {
    highlights = highlights.map(tr.changes)
    for (let e of tr.effects) {
      const char = e.value;
      if (e.is(setHighlights) && tr.state.doc.length) {
        const mark = Decoration.mark({
          attributes: { style: `outline: 2px solid blue` }
        }).range(char, char + 1);
        highlights = Decoration.set([mark]);
      }
    }
    return highlights;
  },
  provide: (f) => EditorView.decorations.from(f)
});

var view = new EditorView({
  doc: "console.log('hello')\n",
  extensions: [basicSetup, javascript(), highlightField],
  parent: document.body
})

var frame = requestAnimationFrame(updateHighlights);
function updateHighlights() {
  try {
    const char = Math.round(Math.random() * view.state.doc.length - 1);
    view.dispatch({ effects: setHighlights.of(char) }); // highlight all still active + new active haps
    frame = requestAnimationFrame(updateHighlights);
  } catch (err) {
    // even though we catch errors here,
    // the range error still crashes
    console.log("err", err);
  }
}

```

---

<div class="post-metadata">

### Author: ![felixroos](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/felixroos/32/2366_2.png) [@felixroos](https://discuss.codemirror.net/u/felixroos)
#### Post date: [July 7, 2023, 7:55am UTC](https://discuss.codemirror.net/t/uncatchable-out-of-range-errors-when-document-changes/4864/7 "2023-07-07T07:55:01Z")

</div>

thank you both for the help! We have now managed to use the codemirror API to make the highlights work much better 🙂 FYI this is the result: [Strudel REPL](https://strudel.tidalcycles.org/?ceWrH19o2-cQ)  
extra thanks to @marijn for the incredible work in the JS space! we use both acorn and codemirror in strudel and it’s amazing what you can do with it
