fix(vscode-ide-companion): comma operator in activate() leaks two Disposables (gemini.diff.accept, onDidChangeWorkspaceFolders)
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript, vscode
- Domain
- tooling
Research direction
Start in packages/vscode-ide-companion/src/extension.ts at activate() and inspect the two context.subscriptions.push(...) calls containing the comma expressions. Remove the extra grouping so all eight Disposables are tracked, then update the mocks and assertions in packages/vscode-ide-companion/src/extension.test.ts to verify gemini.diff.accept and onDidChangeWorkspaceFolders are included.
Written by the indexing model from the issue text.
Description
What happened?
In the VS Code companion extension (packages/vscode-ide-companion/src/extension.ts), the activate() function pushes its Disposables into context.subscriptions in two context.subscriptions.push(...) calls. In each call, two registrations are wrapped in an extra pair of parentheses, which turns them into a single comma expression instead of separate arguments:
// group 1
(vscode.commands.registerCommand('gemini.diff.accept', ...),
vscode.commands.registerCommand('gemini.diff.cancel', ...)),
// group 2
(vscode.workspace.onDidChangeWorkspaceFolders(...),
vscode.workspace.onDidGrantWorkspaceTrust(...)),
A comma expression evaluates both operands but its value is only the last one. So both registrations actually run (the command and listener are created), but only the second Disposable of each group (gemini.diff.cancel, onDidGrantWorkspaceTrust) is passed to push() and tracked in context.subscriptions. The gemini.diff.accept command Disposable and the onDidChangeWorkspaceFolders listener Disposable are never added, so they are never disposed on deactivation.
Consequences:
- On deactivation/reload within the same extension host (e.g. an extension update), the
gemini.diff.acceptcommand stays registered. Re-activation then throwscommand 'gemini.diff.accept' already exists. - The
onDidChangeWorkspaceFolderslistener is never torn down, so a stale listener keeps firingideServer.syncEnvVars()against anIDEServerthat has been stopped.
I reproduced the comma-operator behavior with a small standalone script that uses the exact push(...) argument expressions from the source against stub vscode functions returning tagged Disposables, and counted what actually lands in context.subscriptions:
$ node repro.mjs
Disposables actually pushed into context.subscriptions:
- onDidCloseTextDocument
- registerTextDocumentContentProvider
- registerCommand:gemini.diff.cancel
- onDidGrantWorkspaceTrust
- registerCommand:gemini-cli.runGeminiCLI
- registerCommand:gemini-cli.showNotices
Expected 8 disposables; got 6
MISSING (registered but never pushed -> leaked):
- registerCommand:gemini.diff.accept
- onDidChangeWorkspaceFolders
What did you expect to happen?
All eight Disposables created in activate() should be added to context.subscriptions so they are disposed on deactivation. With the two stray parenthesis pairs removed (each registration its own argument), all eight are pushed:
$ node repro-fixed.mjs
Pushed 8 disposables:
- onDidCloseTextDocument
- registerTextDocumentContentProvider
- registerCommand:gemini.diff.accept
- registerCommand:gemini.diff.cancel
- onDidChangeWorkspaceFolders
- onDidGrantWorkspaceTrust
- registerCommand:gemini-cli.runGeminiCLI
- registerCommand:gemini-cli.showNotices
Suggested direction: remove the extra ( / ) wrapping the two register/listener pairs in activate() so each Disposable is a separate argument to push(). (Happy to send a PR if this is accepted — it's a two-character-region change. The existing extension.test.ts mock returns undefined from registerCommand/listeners, so a regression test would need those mocks to return a tagged Disposable and then assert context.subscriptions contains the gemini.diff.accept command and the onDidChangeWorkspaceFolders listener.)
Client information
Client Information
- Affected package:
packages/vscode-ide-companion(VS Code companion extension), version0.47.0-nightlyline onmain. - Affected symbol:
activate()inpackages/vscode-ide-companion/src/extension.ts. - Platform: platform-independent (JavaScript comma-operator semantics).
Login information
API key
Anything else we need to know?
I'd like to work on this :)
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 43
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from google-gemini/gemini-cli
-
bug(core): explicit `--model gemini-3-pro-preview` silently rewritten to `gemini-3.1-pro-preview` Openarea/agent effort/medium kind/bug priority/p2 status/bot-triaged
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
google-gemini/gemini-cli#29417 · 1 comment ·
-
area/enterprise kind/bug priority/p2 status/bot-triaged
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
google-gemini/gemini-cli#29406 ·
-
area/agent status/need-triage
Difficulty 2/5 Half a day Newbie friendliness 78/100
google-gemini/gemini-cli#29360 ·
-
area/agent kind/bug priority/p2 status/bot-triaged
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
google-gemini/gemini-cli#29315 ·
-
area/non-interactive effort/small kind/bug priority/p2 status/bot-triaged status/need-information
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
google-gemini/gemini-cli#29308 · 2 comments ·
All issues in google-gemini/gemini-cli
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100