microsoft / microsoft/vscode

Agents window renderer OOM during plugin sync: resourceRead Base64 encoding reaches 4 GB heap

Open
#334,892 0 comments 0 reactions 1 assignee Claimed by @TylerLeonhardt View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

Opening Agents window crashes renderer near 4 GB heap limit during plugin resourceRead/base64 transfer

VS Code stable 1.136.1, commit a44adf7f53e00964ab890f9f8758a334f1fc15bc, Windows x64, Electron 42.10.0. Workspace is a WSL UNC folder. No prompt or coding operation is required: simply opening the Agents window triggers the failure.

Observed twice on 2026-09-07:
- 03:31:33: AgentPluginManager starts syncing episodic-memory from the Copilot installed-plugins directory; 03:32:31: renderer exits with reason oom, code -536870904.
- 03:35:07: the same plugin sync starts; 03:36:06: the same renderer OOM.

Both local Crashpad dumps contain:
```
v8-oom-location: Ineffective mark-compacts near heap limit
v8-oom-stack:
bc in sessions.desktop.main.js:434:100588
in =:4846:59861
v8-oom-memory-allocator-size: 3999.05MB / 3999.94MB
v8-oom-memory-allocator-capacity: 4096.00MB
```
The installed bundle maps the caller to _handleReverseRequest, resourceRead:
```js
const result = await this._resourceService.read(identity, URI.parse(params.uri));
reply({ data: encodeBase64(result.bytes), encoding: "base64" });
```
The callee builds the output using four per-character string concatenations for each three input bytes. The agent host plugin sync calls fileService.copy on the plugin directory.

The plugin directory is approximately 751 MiB including node_modules. Its largest file is node_modules/@anthropic-ai/claude-agent-sdk-win32-x64/claude.exe (228410016 bytes). It also includes 20-36 MB ONNX/runtime binaries. The precise file being encoded is not available in the dumps; the largest executable is a strong candidate, not independently proven. The dumps do prove OOM inside this resourceRead encoding path during plugin sync.

Related disablement surprise: user settings already contained
```json
"chat.plugins.enabledPlugins": {
"episodic-memory@superpowers-marketplace": false
}
```
The settings file predates both crashes. However agentPlugins.enablement in global state does not contain a disabled entry for this plugin URI. The installed bundle uses inspect("chat.plugins.enabledPlugins").policyValue for plugin enforcement and a separate URI-based enablement model. Consequently this user-level setting did not prevent synchronization. Please clarify/migrate the user-facing disablement behavior if this setting is now policy-only.

Expected: opening Agents must not exhaust the renderer heap while copying an installed plugin. Large binary transfers should be bounded/chunked or avoid per-character Base64 string accumulation; plugin synchronization should not require materializing huge strings in the UI process. A user-level disablement setting should either work or clearly indicate that it is ineffective.

Validation limits: two real crashes and matching local dump/bundle analysis; no clean-profile repro or patched-build validation yet. No crash dumps, personal file contents, credentials, or session transcripts attached.

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.