Skip to content

Bug: Terminal scroll-to-top caused by xterm parsing errors and WebGL context loss #630

Description

@waleedkadous

Description

The terminal intermittently scrolls to the top during normal use. Investigation with ScrollController debug logging revealed two distinct root causes:

Root Cause 1: xterm.js parsing errors from split escape sequences

xterm.js: Parsing error: {position: 0, code: 9472, currentState: 4}

Code 9472 = 0x2500 (box-drawing ), currentState: 4 = escape state. xterm received a non-escape character while parsing an escape sequence. This means escape sequences are being split across WebSocket frames or data chunks. When xterm hits a parsing error, it can reset its internal buffer state, causing viewportY to jump to 0.

Likely sources of split sequences:

  • Shellper ring buffer replay cutting at escape sequence boundaries
  • WebSocket frame splitting PTY output mid-sequence
  • filterDA regex stripping characters and creating malformed sequences

Root Cause 2: WebGL context loss

WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
webglcontextlost event received
webglcontextrestored event received
WebGL: INVALID_OPERATION: delete: object does not belong to this context (x24)
[Terminal] write caused scroll-to-top, correcting...

When the browser's GPU context is lost (resource pressure, tab switching, GPU driver reset), xterm's WebGL renderer loses state and resets, causing scroll-to-top. The INVALID_OPERATION errors (24 of them) suggest the context restoration isn't clean.

Current Mitigation

ScrollController corrections (handleScroll and term.write callback) catch and correct most scroll-to-top events. But the corrections are reactive — there can be a visual flash before the correction fires.

Proposed Fixes

For parsing errors:

  • Ensure escape sequence integrity in the data pipeline
  • Buffer incomplete escape sequences in Terminal.tsx and only write complete ones to xterm
  • Or: accumulate WebSocket data and flush on requestAnimationFrame boundaries

For WebGL context loss:

  • Handle webglcontextlost / webglcontextrestored events in Terminal component
  • Save scroll position before context loss, restore after context restored
  • Consider falling back to canvas renderer if WebGL context is repeatedly lost

Screenshots

See attached console logs showing both triggers preceding scroll-to-top corrections.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions