Fix stale preset state on included file changes (#4777)#4778
Open
Fix stale preset state on included file changes (#4777)#4778
Conversation
Copilot
AI
changed the title
[WIP] Fix bug with CMake settings not refreshing in VS Code
Fix stale preset state on included file changes (#4777)
Mar 2, 2026
3392fc6 to
207f65a
Compare
- Unify FileWatcher to use single debounced callback for all events (change/create/delete), fixing race condition when external tools regenerate included files via atomic write (delete + create) - Detect root presets file creation inside reapplyPresets() by comparing before/after presetsFileExists state instead of separate handler - Add reapplyPresets() call in configureInternal() so explicit user commands always read fresh preset state from disk - Update tests to reflect unified event handling - Add CHANGELOG entry Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com>
Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com>
207f65a to
29655f6
Compare
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.
This change addresses item #4777
This changes visible behavior for preset file watching and reconfiguration
The following changes are proposed:
onDidCreatehad a separate non-debounced handler, causing a race condition when tools like Conan regenerate included files via atomic write (delete→create): the delete would triggerreapplyPresets()while the file was absent, rebuilding the watcher list without the included file, so the subsequent create event was silently lost.reapplyPresets(): Replaced the separateonCreatePresetsFile()handler with a before/after check ofpresetsFileExistto callupdateActiveProject()only when a root presets file transitions from absent to present.configureInternal(): Explicit user commands (configure, clean-configure, etc.) now callreapplyPresets()before proceeding, so they never depend on the async file watcher having already processed disk changes.Other Notes/Information
The
ensureConfigured()path already had areapplyPresets()call (added for #4502). The new call inconfigureInternal()covers the remaining code paths: direct configure, clean-configure, and clean-configure-with-debugger. SincereapplyPresets()serializes concurrent calls via_reapplyInProgress, double-calls fromensureConfigured()→configureInternal()are effectively no-ops if presets haven't changed on disk.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
40vvsblobprodwus2135.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)78kvsblobprodwus2152.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)b53vsblobprodwus2154.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)km4vsblobprodwus2183.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)l7ivsblobprodwus2133.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)v41vsblobprodwus2175.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)vd2vsblobprodwus2150.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)wztvsblobprodwus2155.vsblob.vsassets.io/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /usr/local/bin/yarn install --frozen-lockfile(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
This section details on the original issue you should resolve
<issue_title>[Bug] Changes in file included from CMakeUserPreset.json didn't applied until VS Code restart</issue_title>
<issue_description>### Brief Issue Summary
In our project we're using conan for managing thirdpartys. When I run the
conan installcommand it will generate the followingCMakeUserPreset.jsonfile in the root directory:Current behavior:
Project settings were generated in the included
build/generated/CMakePresets.jsonIf VS Code is open when the generatedbuild/generated/CMakePresets.jsonfile is changed it won't affect the CMake variables and settings used for configuration. Even if I use theDelete Cache / Reconfigurethe CMake plugin will use the old "cached" settings. The only solution to make it work is to close and reopen VS Code.Expected behavior:
The changes in the
build/generated/CMakePresets.jsonis detected and a new configuration step is triggered with the new settings.CMake Tools Diagnostics
{ "os": "win32", "vscodeVersion": "1.109.5", "cmtVersion": "1.22.28", "configurations": [ { "folder": "c:\\work\\git\\temp_project.git", "cmakeVersion": "3.31.2", "configured": true, "generator": "Visual Studio 17 2022", "usesPresets": true, "compilers": {} } ], "cpptoolsIntegration": { "isReady": true, "hasCodeModel": true, "activeBuildType": "Debug", "buildTypesSeen": [ "Debug", "Release", "MinSizeRel", "RelWithDebInfo" ], "requests": [], "responses": [], "partialMatches": [], "targetCount": 44, "executablesCount": 2, "librariesCount": 19, "targets": [] }, "settings": [ { "communicationMode": "automatic", "useCMakePresets": "auto", "configureOnOpen": true } ] }Debug Log
Can't share the debug outputAdditional Information
No response</issue_description>
<agent_instructions>You are a senior maintainer of vscode-cmake-tools. Fix the bug described in issue #4777 - #4777 : changes to files referenced via the
includedirective inCMakePresets.jsonorCMakeUserPresets.jsonare not detected by the extension until VS Code is restarted. Even "Delete Cache / Reconfigure" does not pick up the new content.Context
The user has a
CMakeUserPresets.jsonthat includes a generated file:{ "version": 4, "vendor": { "conan": {} }, "include": ["build/generated/CMakePresets.json"] }When an external tool (e.g., Conan) regenerates
build/generated/CMakePresets.json, the extension continues using stale cached preset state. The only workaround is restarting VS Code.Investigation Guidance
The bug likely involves two interacting subsystems. You must trace through both VERY carefully and verify whether the analysis below holds before implementing any changes.
Area 1:
FileWatcherevent handling for included filesStart by examining the
FileWatcherclass andwatchPresetsChange()insrc/presets/presetsController.ts. TheFileWatchercurrently receives two separate callbacks: achangeHandler(wired toonDidChangeandonDidDelete) and acreateHandler(wired toonDidCreate). ThechangeHandlercallsreapplyPresets()while thecreateHandlercallsonCreatePresetsFile().Investigate whether this distinction causes problems for included files. The
_referencedFileslist contains all files in the include chain, not just root preset files. TheonCreatePresetsFile()path was designed for whenCMakePresets.jsonorCMakeUserPresets.jsonthemselves are freshly created — it callsupdateActiveProject()in addition toreapplyPresets(). Consider whether applying this create-specific handler to included files introduces issues.Specifically, examine what happens when an external tool regenerates an included file via atomic write (delete + create, or write-to-temp + rename). The OS may emit a
deletefollowed by acreateevent. Trace what happens whenonDidDeletefiresreapplyPresets()while the file is momentarily absent — doesmergeIncludeFiles()insrc/presets/presetsParser.tsfail the expansion with errors, setting the preset state toundefined? If so, does the subsequentonDidCreateevent reliably recover, or can it be lost due to watcher disposal during the rebuild?One possible fix direction: unify the
FileWatcherso all filesystem events (change, create, delete) trigger the same debounced reload path, and remove the separate create handler. TheonCreatePresetsFile()behavior (updateActiveProject()) could instead be detected insidereapplyPresets()by comparing the before/after state ofpresetsFileExists, transitioning from `...🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.