Claude generated from Sentry error log analysis.
Sentry: PYTHON-EDITOR-NEXT-21F
RangeError: Selection points outside of document, 468 events since 31 August 2024, still present in v3.1.11 at a low but steady rate (4 events on v3.1.10, 4 on v3.1.11).
The suspected cause below is a hypothesis with no reproduction. Filing it mainly to record the browser/guard mismatch, which is the one concrete finding.
Not part of #1317
Worth stating up front, because it looks like the tile crashes and turns up in the same crash cascades. It is not one of them:
- It first appeared in August 2024, long before the tile rewrite.
- It occurs on v3.1.7 (23 events), which shipped
@codemirror/view 6.26.3 — pre-tile.
It does co-occur with the #1317 group: one session on 10 Sep 2026 threw this, Invalid position, No tile at position and HierarchyRequestError within a few seconds. That is probably a fragile editor state producing several independent faults rather than a shared cause.
Stack
Outermost first; the last frame is where it threw.
DOMObserver.onSelectionChange (@codemirror/view)
DOMObserver.flush
applyDOMChange
EditorView.dispatch
resolveTransaction (@codemirror/state)
Transaction.create
new Transaction
checkSelection <- throws
No frames in our code. mechanism is an addEventListener handler, i.e. unhandled.
Suspected cause
onSelectionChange (domobserver.ts:170 upstream) maps the browser's current DOM selection onto document positions and dispatches it. checkSelection rejects the transaction because the resulting range is past the end of the document, so the DOM selection describes text the document no longer has.
Upstream already guards against precisely this ordering problem, but narrowly:
// Deletions on IE11 fire their events in the wrong order, giving
// us a selection change event before the DOM changes are
// reported.
// Chrome Android has a similar issue when backspacing out a
// selection (#645).
if ((browser.ie && browser.ie_version <= 11 || browser.android && browser.chrome) && ...)
this.flushSoon()
else
this.flush(false)
The finding: our traffic is not what the guard covers
The guard applies to IE11 and Chrome on Android. Our events are desktop Chromium, with no Android at all:
| Browser |
Events |
| Chrome 150 |
73 |
| Chrome 147 |
30 |
| Chrome 151 |
26 |
| Edge 150 |
18 |
| Edge 151 |
16 |
| Chrome 149 |
13 |
| Chrome 142 |
9 |
| Safari 17.6 |
4 |
| OS |
Events |
| Windows >=10 |
80 |
| macOS >=10.15.7 |
64 |
| ChromeOS |
51 |
So either the same event-ordering race occurs on desktop Chromium in a case upstream has not accounted for, or the cause is different and the resemblance is misleading.
Alternative explanation not ruled out
One of our own extensions could be dispatching a selection against a stale document. We have several that dispatch from async sources — the language server view, lint, and the structure-highlighting measure pass. The absence of our frames in the trace argues against it, since the throw happens inside the observer's own flush rather than in a transaction we initiated, but it is not proof.
Caveat on the numbers
Lifetime count is 468, but only 195 events carry a release tag: Sentry's tag index has 90-day retention, so the release breakdown is a recent window, not full history. The pre-tile v3.1.7 attribution is within that window and is safe to rely on.
Related
Claude generated from Sentry error log analysis.
Sentry: PYTHON-EDITOR-NEXT-21F
RangeError: Selection points outside of document, 468 events since 31 August 2024, still present in v3.1.11 at a low but steady rate (4 events on v3.1.10, 4 on v3.1.11).The suspected cause below is a hypothesis with no reproduction. Filing it mainly to record the browser/guard mismatch, which is the one concrete finding.
Not part of #1317
Worth stating up front, because it looks like the tile crashes and turns up in the same crash cascades. It is not one of them:
@codemirror/view6.26.3 — pre-tile.It does co-occur with the #1317 group: one session on 10 Sep 2026 threw this,
Invalid position,No tile at positionandHierarchyRequestErrorwithin a few seconds. That is probably a fragile editor state producing several independent faults rather than a shared cause.Stack
Outermost first; the last frame is where it threw.
No frames in our code.
mechanismis anaddEventListenerhandler, i.e. unhandled.Suspected cause
onSelectionChange(domobserver.ts:170upstream) maps the browser's current DOM selection onto document positions and dispatches it.checkSelectionrejects the transaction because the resulting range is past the end of the document, so the DOM selection describes text the document no longer has.Upstream already guards against precisely this ordering problem, but narrowly:
The finding: our traffic is not what the guard covers
The guard applies to IE11 and Chrome on Android. Our events are desktop Chromium, with no Android at all:
So either the same event-ordering race occurs on desktop Chromium in a case upstream has not accounted for, or the cause is different and the resemblance is misleading.
Alternative explanation not ruled out
One of our own extensions could be dispatching a selection against a stale document. We have several that dispatch from async sources — the language server view, lint, and the structure-highlighting measure pass. The absence of our frames in the trace argues against it, since the throw happens inside the observer's own flush rather than in a transaction we initiated, but it is not proof.
Caveat on the numbers
Lifetime count is 468, but only 195 events carry a release tag: Sentry's tag index has 90-day retention, so the release breakdown is a recent window, not full history. The pre-tile v3.1.7 attribution is within that window and is safe to rely on.
Related
Invalid positionerrors, is the closest prior art for an async-vs-document race in this codebase, and has a reproduction technique (inserting an artificial delay before a tooltip is removed) that may be adaptable here.