microsoft / microsoft/vscode

`run_in_terminal` automatically embeds image paths from stdout without an aggregate limit, causing renderer OOM

Open
#332,145 3 comments 0 reactions 1 assignee Claimed by @anthonykim1 View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

- Copilot Chat Extension Version: 0.62.0
- VS Code Version: 1.134.0 Stable (`110a328ea54b42367b803ec53ee0bf52ef26b419`)
- OS Version: Windows 11 Pro 25H2, build 26200.9168, x64
- Feature: Agent mode
- Selected model: GPT 5.6
- Logs: Not attached. The cause is directly reproducible and the relevant implementation is identified below.

Steps to Reproduce:

1. Open a workspace containing many image files smaller than 5 MiB.
2. Start an Agent chat with the built-in terminal tool enabled.
3. Have the agent run a command that prints path-like image filenames, such as `git status --short --untracked-files=all`.
4. Continue using the task or reopen it and observe rapidly increasing renderer memory.

The built-in `run_in_terminal` tool scans the full terminal output for paths ending in PNG, JPEG, GIF, WebP, or BMP. It resolves every matching path relative to the terminal working directory, reads the file, and appends its bytes to the tool result.

The relevant result path is effectively:

```js
const cwd = await terminal.instance.getCwdResource();
const images = await this._extractImagesFromOutput(fullRawOutput, cwd);

return {
content: [
{ kind: "text", value: processedText },
...images
]
};
```

`_extractImagesFromOutput` enforces a 5 MiB per-file limit but has no image-count or aggregate-byte limit. It also receives the full raw output, so terminal output truncation and `chat.tools.terminal.outputCompaction` do not prevent the issue.

This means commands such as `git status`, `find`, recursive directory listings, asset inventories, and build reports can unintentionally attach every image path they print. The image bytes are subsequently serialized as base64 into the task state and duplicated between tool-result metadata and response details.

In my reproduction:

- Approximately 120 KiB of terminal text produced 72 embedded image parts.
- One serialized terminal result grew to approximately 33.5 MiB.
- The active task exceeded 500 MiB on disk.
- Reopening or rendering the task expanded memory usage until the renderer reached its heap limit and crashed with OOM.

Expected behavior:

Terminal stdout should be returned as text. Paths printed by arbitrary commands should not be dereferenced and attached automatically. Images should only be loaded following an explicit image-view request.

At minimum, please add an option such as:

```json
"chat.tools.terminal.extractImagesFromOutput": false
```

Image extraction should preferably default to disabled. If retained, it should have conservative image-count and aggregate-byte limits and should only inspect output retained after compaction.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.