microsoft / microsoft/vscode-documentdb

SchemaStore.dispose() writes to an already-disposed output channel: "Channel has been closed" on every shutdown

Open Beginner friendly
#885 0 comments 0 reactions 0 assignees View on GitHub

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

  1. Install vscode-documentdb-0.10.0.vsix.
  2. Open a window and let the extension activate.
  3. Close the window.
  4. 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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.