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
SchemaStore could be masked by this one.
Suggested fix
Any of:
- Register
SchemaStore before ext.outputChannel so 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.
Reproduced against the CI-built
vscode-documentdb-0.10.0.vsixfrom #883 (artifact of run 31513450303).Summary
Every extension-host shutdown logs an unhandled error while disposing the extension's subscriptions.
SchemaStore.dispose()callslogStats(), which writes to the shared output channel — but that channel has already been disposed by then, so the write throws.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 intocontext.subscriptionsbefore it registersSchemaStore:VS Code disposes
context.subscriptionsin registration order, so the channel atiis closed beforeSchemaStoreatjruns its owndispose().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 andappendLinethrows.Steps to reproduce
vscode-documentdb-0.10.0.vsix.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:
SchemaStorecould be masked by this one.Suggested fix
Any of:
SchemaStorebeforeext.outputChannelso it disposes first; orlogStats()bail when the channel is closed (track a disposed flag rather than relying on?.); ordispose()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.