fix: defer install prompt until after manager timeout to prevent false positives#1496
Merged
eleanorjboyd merged 2 commits intomainfrom May 1, 2026
Merged
Conversation
f2201d0 to
6da90bb
Compare
Previously, checkExtension would show the 'install extension' prompt inside a setImmediate callback — just one tick after startup. If the extension host hadn't fully initialized yet, getExtension() could return undefined even for installed extensions, causing a false prompt. Now the install prompt is only shown after the full 30-second timeout expires AND getExtension() still returns undefined. This gives the extension host ample time to initialize. Additionally, if the extension IS installed but the manager never registered (activation failure), we log a warning instead of prompting to install. Changes: - Move install prompt logic from checkExtension into promptInstallExtensionIfMissing, called only after timeout - checkExtension now only attempts activation (no install prompts) - Add guard: if extension is installed but manager never registered, log a warning instead of prompting to install - Add 5 regression tests for the race condition scenarios - Add _resetManagerReadyForTesting() helper for test isolation Fixes #1465 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6da90bb to
6857c59
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses a startup race where getExtension() can temporarily return undefined while the VS Code extension host is still initializing, causing a false “install ms-python.python” prompt even when the extension is installed.
Changes:
- Defers the install prompt until the manager registration timeout expires, preventing false positives during startup.
- Refactors
checkExtension()to only perform best-effort activation (no prompting). - Adds regression unit tests covering timeout vs. successful registration scenarios for both env and package managers.
Show a summary per file
| File | Description |
|---|---|
src/features/common/managerReady.ts |
Moves install prompting behind the manager timeout and simplifies early extension checks to activation-only. |
src/test/features/common/managerReady.unit.test.ts |
Adds unit tests validating the deferred prompt behavior and race-condition scenarios. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 4
- Wrap promptInstallExtensionIfMissing with void/.catch for unhandled rejections - Attempt activation post-timeout when extension is installed but inactive - Fix question punctuation (period → question mark) - Deduplicate install prompts per extension ID per session via prompted Set Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
edvilme
commented
Apr 30, 2026
Contributor
Author
edvilme
left a comment
There was a problem hiding this comment.
All 4 review comments addressed in commit 2151164:
- Unhandled promise rejection - Wrapped with
void ... .catch(traceError) - Activate inactive extension post-timeout - Now attempts
ext.activate()when installed but inactive - Punctuation - Changed period to question mark
- Deduplicate install prompts - Added module-level
promptedSet keyed by extId
eleanorjboyd
approved these changes
May 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: Only show install prompt after manager timeout, not during startup
Fixes #1465
Problem
Users consistently see a false "Do you want to install extension ms-python.python to enable ms-python.python:venv support" prompt despite having the extension installed. This happens across Windows/Linux, persists despite reinstalls, and is a race condition during startup.
Root Cause
The race condition:
checkExtension()which queriesgetExtension()after just 1 tick (setImmediate)B can execute BEFORE A finishes —
getExtension()returnsundefinedeven though the extension IS installed, triggering a false install prompt.The Fix
Separate the two concerns:
checkExtension()— fires early, but only does activation (harmless if it sees stale state — worst case it's a no-op). Never prompts to install.promptInstallExtensionIfMissing()— fires ONLY after the 30s timeout inwithManagerTimeout(), whengetExtension()is guaranteed to be reliable.The install prompt can no longer race against extension host initialization because it's gated behind the same 30s timeout that already exists for "manager didn't register."
Flow (annotated)
Changes
withManagerTimeout: Now callspromptInstallExtensionIfMissing()on timeout expirypromptInstallExtensionIfMissing(new): ChecksgetExtension()after 30s; only prompts if extension truly missing; logs warning if installed but manager never registeredcheckExtension: Simplified to only attempt activation — no install prompts