Claude generated from Sentry error log analysis.
Sentry: PYTHON-EDITOR-NEXT-1HJ
RangeError: Invalid position -1 in document of length N, 4,181 events since 29 April 2024, still present in v3.1.11. This is the largest single group in the project by event count, and unlike the tile crashes in the umbrella issue it is ours, not upstream.
Cause
positionsForNode in src/editor/codemirror/structure-highlighting/view.ts:116:
const bottomPos = skipBodyTrailers(
state,
diagnostics,
end - 1,
topLineNumber
);
skipBodyTrailers immediately does state.doc.lineAt(position) (doc-util.ts:35), which throws for a negative position. So whenever end is 0, we pass -1 and throw.
end is either block.bodyStart or block.bodyEnd, from the two calls at view.ts:149 and view.ts:156. Both are raw syntax-tree offsets produced by codeBlocks in blocks.ts, so a node positioned at offset 0 reaches the subtraction unguarded. Lezer error recovery on an incomplete or badly indented document is the plausible source of such a node — the reported document lengths are small (double digits), consistent with mid-typing rather than a finished program.
The -1 in the message is the tell: it is not a stale-position problem like #1053, it is an unguarded arithmetic edge.
Suggested fix
Guard at the call site rather than inside skipBodyTrailers. Its documented contract takes "a document character position", and lineAt throwing on an invalid one is reasonable; the caller is what produces the invalid value. Bailing out (returning undefined, as the function already does when it runs past min) looks right for end === 0, since a block whose body starts at offset 0 has nothing above it to highlight.
Worth a unit test in doc-util.test.ts or view.ts's coverage for end === 0.
Related
Claude generated from Sentry error log analysis.
Sentry: PYTHON-EDITOR-NEXT-1HJ
RangeError: Invalid position -1 in document of length N, 4,181 events since 29 April 2024, still present in v3.1.11. This is the largest single group in the project by event count, and unlike the tile crashes in the umbrella issue it is ours, not upstream.Cause
positionsForNodeinsrc/editor/codemirror/structure-highlighting/view.ts:116:skipBodyTrailersimmediately doesstate.doc.lineAt(position)(doc-util.ts:35), which throws for a negative position. So wheneverendis0, we pass-1and throw.endis eitherblock.bodyStartorblock.bodyEnd, from the two calls atview.ts:149andview.ts:156. Both are raw syntax-tree offsets produced bycodeBlocksinblocks.ts, so a node positioned at offset 0 reaches the subtraction unguarded. Lezer error recovery on an incomplete or badly indented document is the plausible source of such a node — the reported document lengths are small (double digits), consistent with mid-typing rather than a finished program.The
-1in the message is the tell: it is not a stale-position problem like #1053, it is an unguarded arithmetic edge.Suggested fix
Guard at the call site rather than inside
skipBodyTrailers. Its documented contract takes "a document character position", andlineAtthrowing on an invalid one is reasonable; the caller is what produces the invalid value. Bailing out (returningundefined, as the function already does when it runs pastmin) looks right forend === 0, since a block whose body starts at offset 0 has nothing above it to highlight.Worth a unit test in
doc-util.test.tsorview.ts's coverage forend === 0.Related
RangeErrorin the samepositionsForNode, but viaview.lineBlockAtrather thanskipBodyTrailers, and was closed in 2022.