Skip to content

[Code structure] skipBodyTrailers passed -1, throwing Invalid position #1318

Description

@microbit-matt-hillsdon

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions