From 13262e38d8ea96ebb2b0fbf370acd876e06cf07e Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Tue, 10 Mar 2026 14:58:55 -0400 Subject: [PATCH] fix `cannot read properties of undefined (reading 'getCell')` error that causes terminal benchmarks to fail (#300517) fix error --- .../contrib/terminal/browser/xterm/xtermTerminal.ts | 12 +++++++++--- .../test/browser/chatTerminalCommandMirror.test.ts | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index ea122a15c23..b043728acf3 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -47,6 +47,7 @@ import type { IProgressState } from '@xterm/addon-progress'; import type { CommandDetectionCapability } from '../../../../../platform/terminal/common/capabilities/commandDetectionCapability.js'; import { URI } from '../../../../../base/common/uri.js'; import { isNumber } from '../../../../../base/common/types.js'; +import { clamp } from '../../../../../base/common/numbers.js'; const enum RenderConstants { SmoothScrollDuration = 125 @@ -964,16 +965,21 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach this.raw.loadAddon(this._serializeAddon); } + const lastLine = this.raw.buffer.active.length - 1; + if (lastLine < 0) { + return ''; + } + const hasValidEndMarker = isNumber(endMarker?.line); - const start = isNumber(startMarker?.line) && startMarker?.line > -1 ? startMarker.line : 0; + const start = clamp(isNumber(startMarker?.line) && startMarker.line > -1 ? startMarker.line : 0, 0, lastLine); let end = hasValidEndMarker ? endMarker.line : this.raw.buffer.active.length - 1; if (skipLastLine && hasValidEndMarker) { end = end - 1; } - end = Math.max(end, start); + end = clamp(Math.max(end, start), start, lastLine); return this._serializeAddon.serialize({ range: { - start: startMarker?.line ?? 0, + start, end } }); diff --git a/src/vs/workbench/contrib/terminal/test/browser/chatTerminalCommandMirror.test.ts b/src/vs/workbench/contrib/terminal/test/browser/chatTerminalCommandMirror.test.ts index 3d91b41d178..9a30e722fe2 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/chatTerminalCommandMirror.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/chatTerminalCommandMirror.test.ts @@ -202,6 +202,17 @@ suite('Workbench - ChatTerminalCommandMirror', () => { strictEqual(mirrorText.includes('before'), false); }); + test('disposed start marker does not throw in VT serialization', async () => { + const source = await createXterm(); + await write(source, 'line 1\r\nline 2'); + + const startMarker = source.raw.registerMarker(0)!; + startMarker.dispose(); + + const vt = await source.getRangeAsVT(startMarker, undefined, true); + strictEqual(typeof vt, 'string'); + }); + test('incremental mirroring appends correctly', async () => { const source = await createXterm(); const marker = source.raw.registerMarker(0)!;