microsoft / microsoft/vscode-documentdb
SchemaStore.dispose() writes to an already-disposed output channel: "Channel has been closed" on every shutdown
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 31
- Forks
- 22
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 21
Description
Reproduced against the CI-built vscode-documentdb-0.10.0.vsix from #883 (artifact of run 31513450303).
Summary
Every extension-host shutdown logs an unhandled error while disposing the extension's subscriptions. SchemaStore.dispose() calls logStats(), which writes to the shared output channel — but that channel has already been disposed by then, so the write throws.
[error] An error occurred when disposing the subscriptions for extension 'ms-azuretools.vscode-documentdb':
[error] Error: Channel has been closed
at AzExtLogOutputChannel.appendLine (main.js:2:362407)
at AzExtLogOutputChannel.appendLog (main.js:2:362726)
at SchemaStore.logStats (main.js:2:2120687)
at SchemaStore.dispose (main.js:2:2123726)
Observed in 4 of 6 windows that reached a clean shutdown. It is the only extension-level error in any of those runs — everything else is clean.
Cause
The ordering is deterministic, not a race. activate() registers the output channel into context.subscriptions before it registers SchemaStore:
ext.outputChannel -> subscriptions[i]
…
SchemaStore.getInstance() -> subscriptions[j] where j > i
VS Code disposes context.subscriptions in registration order, so the channel at i is closed before SchemaStore at j runs its own dispose(). logStats() then writes to a closed channel.
Worth noting the ext.outputChannel?. optional chaining in that path reads as a guard but isn't one — the object still exists, it is merely closed, so ?. passes and appendLine throws.
Steps to reproduce
- Install
vscode-documentdb-0.10.0.vsix. - Open a window and let the extension activate.
- Close the window.
- Check
logs/<session>/window1/exthost/exthost.log.
Expected: shutdown completes without errors.
Actual: the stack above, on most shutdowns.
Impact
Not user-visible — it is log noise at shutdown, and no functionality is lost. Two reasons it is still worth fixing:
- It fires on every window close, reload, and extension update, so it is persistent noise in any log a user attaches to a bug report.
- VS Code aborts the remainder of that subscription-disposal pass when a disposable throws, so a genuine cleanup failure registered after
SchemaStorecould be masked by this one.
Suggested fix
Any of:
- Register
SchemaStorebeforeext.outputChannelso it disposes first; or - Have
logStats()bail when the channel is closed (track a disposed flag rather than relying on?.); or - Move the stats logging out of
dispose()entirely — emitting telemetry at shutdown is fine, but writing to a channel that is itself a subscription is inherently order-dependent.
The first is the smallest change; the second is the most robust if anything else ever logs during disposal.
Suggested milestone
0.10.1 — not a release blocker for 0.10.0 unless the reorder turns out to be a confident one-liner.
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.
Research direction
Start in the extension activation path where ext.outputChannel and SchemaStore.getInstance() are added to context.subscriptions, then inspect SchemaStore.dispose() and logStats(). Reproduce by activating the extension, closing the VS Code window, and checking the exthost log; done means shutdown produces no "Channel has been closed" error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100