← Back to VS Code Extension Drift Check

Why VS Code doesn't warn you when an extension is delisted

Delisting an extension from a marketplace stops it from being newly installed and stops it from being offered as an update. It does nothing to a copy already on a developer's disk: VS Code has no push mechanism that reaches back into an existing install to warn or remove it. If you installed the extension before it was pulled, it keeps running exactly as it did the day you installed it — auto-update just quietly stops finding anything newer to offer.

Two times this gap actually mattered

CampaignMarketplaceSinceWhat happened
GlassWormOpen VSX2026-01-31Self-propagating campaign that has abused at least 72 extensions, mimicking widely used linters, formatters, code runners, and AI-coding-assistant tools to reach developer machines.
Nx ConsoleVS Code Marketplace2026-05-18A trojanized build was live for roughly 18 minutes before takedown, distributing a credential stealer that harvested 1Password vaults, Claude Code configuration, and npm/GitHub/AWS tokens from anyone who updated during that window.

Sources: The Hacker News on GlassWorm, The Hacker News on the Nx Console breach. In both cases, developers who had already installed the compromised build before takedown had no in-editor signal that anything had changed.

What the two checks actually answer

The deterministic diff (snapshot + diff, no network) answers "did this extension's declared surface change since I last looked" — a new unconditional-startup trigger, a new extension dependency, or a changed entry point. It needs nothing but two snapshots you already have, and it works the moment an update lands, before anyone has reported anything.

The live check (check, the only command that touches the network) answers a different, narrower question: does this extension's id still resolve on the VS Code Marketplace right now. A "not found" result is the closest signal this tool can offer to "this may have been pulled" — but it is not proof. The same result appears for an extension that was never published to the Marketplace at all (installed instead from Open VSX, a `.vsix` sideload, or a private registry). Read it as a prompt to check by hand, not a verdict.

Wiring it into CI as a gate

Commit a reviewed baseline snapshot once, then compare against it on a schedule or before an image is rebuilt:

- name: Check installed extensions for a surface change
  run: |
    node ventures/vscode-extension-drift-check/cli.mjs snapshot --out /tmp/current.json --dir "$HOME/.vscode/extensions"
    node ventures/vscode-extension-drift-check/cli.mjs diff extension-baseline.json /tmp/current.json

The command exits non-zero only when an extension's surface changed since the baseline — a plain version bump, or a change on the side the browser page or a code --list-extensions-style snapshot cannot see, is reported but does not fail the build on its own. Accept a specific extension's change with --ignore id once you've reviewed it, the same way npm-lifecycle-script-check handles an accepted install script.

Common questions

If it's pulled from the marketplace, doesn't VS Code just remove it?

No. Delisting stops new installs and stops offering an update — it does not touch what is already on disk. An extension you installed before it was pulled keeps running exactly as before, with no dialog, no notification, and no automatic uninstall.

Does a surface-changed flag mean an extension is malicious?

No. The flags are a structural comparison against the incidents above (a broadened startup trigger, a new extension dependency, a changed entry point) — not a determination. A legitimate feature release can also add an activation event or a dependency. A flag means read this one; it is not a verdict.

Why check the Marketplace instead of scanning the extension's code?

Scanning bundled, often-minified JavaScript for malicious intent is a much harder, much less certain problem, and other free tools already attempt it. Checking whether an id still resolves needs no code analysis and no database: it is a direct factual question the Marketplace itself answers, and it is exactly the question a pulled-extension incident makes worth asking first.