ProjectData: "Access to the path is denied." when migrating a version=1 .lscache on a non-system volume (11.0.2)
@genlu is already working on this.
Since Sep 17, 2026.
Assessment
This issue has not been assessed yet.
Description
Type: Bug
Summary
Since C# Dev Kit 11.0.2, every dotnet build run from a VS Code integrated terminal emits one warning per project:
…\ms-dotnettools.csdevkit-11.0.2-win32-x64\dist\msbuild\Microsoft.NET.ProjectData.targets(548,5):
warning ProjectData: failed to write project-data file for D:\repo\src\Foo\Foo.csproj: Access to the path is denied.
The cause is the version=1 → version=2.2 migration of an existing <project>.csproj.lscache, which fails when the project lives on a volume other than the one holding %LOCALAPPDATA%. The stale cache file is then never updated, and the warning repeats on every build.
This is disruptive for repos that treat build warnings as errors, and it is easy to misread as a project/compiler problem: the warning names the user's .csproj, not the extension's own cache.
Environment
- C# Dev Kit
11.0.2(win32-x64), VS Code Insiders - .NET SDK 10.0.401, Windows 11 Pro 26200
- Repo on
D:\,%LOCALAPPDATA%onC:\ - Pre-existing
*.csproj.lscachefiles written by an earlier Dev Kit version (version=1header)
How it triggers
The extension injects MSBuild hooks into the integrated terminal environment (dist/extension.js, updateTerminalEnvironment):
CustomAfterMicrosoftCommonTargets = …/dist/msbuild/Microsoft.NET.ProjectData.targets
CustomAfterMicrosoftCommonCrossTargetingTargets = (same)
EnableProjectDataOnBuild = true
EnableProjectDataInProjectFolder = true|false (from dotnet.projectsystem.cacheInProjectFolder)
So an ordinary terminal build runs _WriteProjectData. Line 548 is the in-project-folder writer.
Note also Microsoft.NET.ProjectData.targets:62:
<EnableProjectDataInProjectFolder Condition="Exists('$(MSBuildProjectFullPath).lscache')">true</EnableProjectDataInProjectFolder>
Any leftover .lscache forces project-folder mode back on regardless of the user's dotnet.projectsystem.cacheInProjectFolder setting — so a user who has since switched to the user-folder default still hits the failing path.
Steps to reproduce
- On a machine where
%LOCALAPPDATA%is onC:\, create a minimalnet10.0console project on a different volume (e.g.D:\repro). - Place a
version=1Repro.csproj.lscachenext to the.csproj(one written by an older Dev Kit, or any file whose first line isversion=1). - In a shell with the four environment variables above set (or simply a VS Code integrated terminal with C# Dev Kit 11.0.2 active), run:
dotnet build --no-incremental
Expected: the cache is rewritten as version=2.2, no warning.
Actual: warning ProjectData: failed to write project-data file for …: Access to the path is denied. and the .lscache stays at version=1.
Note the warning only appears when CoreCompile actually runs; an up-to-date build hides it.
Isolation
| Project location | Existing .lscache |
Result |
|---|---|---|
D:\repo\src\Foo |
stale version=1 |
warning, file left untouched |
D:\repo\src\Foo |
none | clean, writes version=2.2 |
throwaway project on D:\ |
same stale bytes copied in | warning |
throwaway project on C:\…\Temp\… |
same stale bytes copied in | clean, upgraded to version=2.2 |
Identical file contents; only the volume differs. Reproduced consistently across several runs.
Ruled out:
- Not permissions.
icaclsshows full Modify for the user on the file, its directory and the repo root; the file isArchiveonly (not read-only). - Not a lock. Another process can
File.Open(path, Open, ReadWrite, FileShare.None)andFile.WriteAllTextthe same file successfully while the build is failing. - Not MSBuild node reuse. Fails identically with
-nodeReuse:falseandMSBUILDDISABLENODEREUSE=1. - Not repo-specific. A brand-new project inside the same repo tree builds cleanly — until a
version=1cache is dropped next to it. - Not the file's identity. A fresh
cpof the sameversion=1bytes reproduces it.
Likely mechanism
The failing operation appears to be the legacy-cache migration into the user-folder store rather than the .lscache write itself. Supporting evidence: %LOCALAPPDATA%\Microsoft\dotnet-projectdata contains four empty shard directories, created at the moment of the first failing build — exactly one per affected project — while populated shards exist for projects that migrated successfully. Microsoft.NET.ProjectData.Tasks.dll contains lscache-donor-index.json, DOTNET_PROJECTDATA_DONOR_ENABLED and Failed to delete temporary donor index file {0}: {1}, suggesting a donor/migration step. A cross-volume move or File.Replace there would surface as ERROR_ACCESS_DENIED.
Diagnosability
The message is Access to the path is denied. with no path, which matches .NET's UnauthorizedAccess_IODenied_NoPathName (used when the failing path is unavailable to the exception). The only path in the warning is the user's .csproj, which points the reader at the wrong file entirely. Including the path actually being written would have made this a one-minute diagnosis instead of a long one.
Workaround
Delete the stale *.csproj.lscache files. They are regenerable, and removing them also clears the :62 override so caching returns to the user-folder default.
Suggested fixes
- Make the
version=1→version=2.2migration volume-safe (copy + delete rather than move/replace across volumes), or fall back to discarding the legacy file and writing fresh — the cache is regenerable, so a failed migration should never surface as a build warning. - Include the path that actually failed in the warning text, not only the
.csproj. - Consider downgrading a cache-write failure from a build warning to a message; it does not affect build correctness, and it breaks builds in repos configured to treat warnings as errors.
Extension version: 11.0.2
VS Code version: Code - Insiders 1.139.0-insider (046944034292b5479b4e9a50ad1a508033ffb64f, 2026-09-17T03:41:14Z)
OS version: Windows_NT x64 10.0.26200
Modes:
System Info
| Item | Value |
|---|---|
| CPUs | Intel(R) Core(TM) i7-14700HX (28 x 2304) |
| GPU Status | 2d_canvas: enabled GPU0: VENDOR= 0x8086, DEVICE=0xa788 [Intel(R) UHD Graphics], DRIVER_VENDOR=Intel, DRIVER_VERSION=32.0.101.7085 ACTIVE GPU1: VENDOR= 0x10de, DEVICE=0x28b8 [NVIDIA RTX 2000 Ada Generation Laptop GPU], DRIVER_VERSION=32.0.15.9595 GPU2: VENDOR= 0x1414, DEVICE=0x008c [Microsoft Basic Render Driver], DRIVER_VERSION=10.0.26100.9278 Machine model name: Machine model version: direct_rendering_display_compositor: disabled_off_ok gpu_compositing: enabled multiple_raster_threads: enabled_on opengl: enabled_on rasterization: enabled raw_draw: disabled_off_ok skia_graphite: disabled_off trees_in_viz: disabled_off video_decode: enabled video_encode: enabled webgl: enabled webgpu: enabled webnn: disabled_off |
| Load (avg) | undefined |
| Memory (System) | 63.56GB (33.19GB free) |
| Process Argv | --crash-reporter-id 846b7a86-2d60-4215-8e4a-4edd3a78e974 |
| Screen Reader | no |
| VM | 0% |
A/B Experiments
vsliv368cf:30146710
pythonvspyt551:31249597
nativeloc1:31118317
dwcopilot:31158714
dwoutputs:31242946
copilot_t_ci:31333650
g012b348:31231168
pythonrdcb7:31268811
pythonpcpt1:31399616
6518g693:31302842
envsactivate1:31349248
editstats-enabled:31346256
cloudbuttont:31366566
3efgi100_wstrepl:31403338
56b7f661:31457055
cp_cls_t_966_ss:31526232
4je02754:31455664
c3h7c220:31478652
cp_cls_c_1081:31454833
conptydll_true:31485575
e9c30283:31453065
c9b86496:31447327
ei9d7968:31462942
f860i809:31458078
89g7j272:31506658
hhf17803:31462392
i2gc6536:31472020
52612955:31508042
ddid_c:31478205
hmra_i5g22:31518061
7df3h592:31491241
cp_cls_t_1082:31535311
logging_enabled_new:31490725
jb_cp_cls_t_632:31543129
32d76977:31503652
ha629193:31508444
a1ije391_t:31533808
jbcp_cls_pctr_t:31531130
cp_intellij_t_nes:31548657
24a33675:31583069
jf4hg949:31526829
hide-eh-duplicates:31543293
replace-eh-with-ah:31545853
ihg5j128:31534457
nes-ex-cf-euporie-03:31542847
enable_editor_pane_layout:31551200
52258b4d:31547953
36h42362:31560305
c7c27ce7:31551212
1h923230:31564177
treatment-23-1:31555779
unuse_dynamic_mcp:31555281
0c1h4866:31562347
5b8j3302:31564600
autotiers:31584973
mangle-name-treatment:31568054
allow-signed-out:31574470
codex-agent-enabled:31566739
intellij_nes_preview_t:31580086
64a8d082:31573709
issue8950-5d26a188:31574957
multiv2:31574987
ae8b2313:-9
2bfb8b39:31576696
outline:31581109
1cff76af:31580265
96d59efc:31580278
85d09606-suggestts7:31585348
links-treatment:31581067
7g328426_fixed:31583679
54hd3363:31585488
permission_prompt_treatment:1332566
ccr_pr_nudge_adoption:1319471
vsc_wsm_c:1324224
ce50c479:1394169
3aced641:1389836
sem_714gi995:1394171
- Dominant language
- No language data
- Stars
- 321
- Forks
- 54
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 2
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/vscode-dotnettools
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
microsoft/vscode-dotnettools#3563 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
microsoft/vscode-dotnettools#3561 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
microsoft/vscode-dotnettools#3560 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
microsoft/vscode-dotnettools#3557 ·
-
AIEngineering
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
microsoft/vscode-dotnettools#3286 ·