Repository navigation
Bug: csproj-analyzer-paths-stale-after-dependabot-bump-breaks-fresh-clone #597
Description
- Work Mode: full-bug
Summary
packages.config pins Meziantou.Analyzer 3.0.174 and Roslynator.Analyzers 4.16.1, but 80 unconditional <Analyzer Include> items across 16 first-party .csproj files still point at the previous 3.0.156 / 4.16.0 package folders. A clean checkout restores only the pinned versions, so those 80 analyzer paths do not exist and the build fails with error CS0006. A fresh clone of main cannot build. CI passes only because its NuGet cache has a prefix restore-keys fallback that restores a pre-bump packages tree.
Environment
- OS/version: Windows 11 Pro 10.0.26200
- Python version: n/a - C# / MSBuild
- Command/flags used:
msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true - Data source or fixture:
mainatd15f9510; introduced by PR Bump the analyzers-dev-deps group with 2 updates #573 (mergedeb6f6836)
Steps to Reproduce
- Clone the repository into a directory with no pre-existing
packages/folder, or deletepackages/entirely. - Run
nuget restore TaskMaster.sln. OnlyMeziantou.Analyzer.3.0.174andRoslynator.Analyzers.4.16.1are installed, because those are whatpackages.configpins. - Run the analyzer build command above.
- Observe the failure.
- For the CI side, inspect
.github/workflows/_build-analyzers.ymland note the cacherestore-keysprefix fallback.
Expected Behavior
A clean checkout restores the pinned analyzer packages and builds. <Analyzer Include> paths agree with the versions packages.config pins.
Actual Behavior
The 80 stale <Analyzer Include> paths reference package folders that a clean restore never creates, so MSBuild reports error CS0006 (metadata file not found) and exits 1.
Counted over tracked first-party project files only (git ls-files '*.csproj', 18 files):
Meziantou 3.0.156 lines : 16
Roslynator 4.16.0 lines : 64
TOTAL stale lines : 80 across 16 files
lines citing 3.0.174 / 4.16.1 : 0
The items carry no Condition attribute, so they are evaluated unconditionally and a missing file is fatal rather than skipped. PR #573 was a Dependabot group bump that correctly updated packages.config and the Condition-guarded Import / Error lines, but not these hand-authored items - they were added by issue #181 and sit under the comment <!-- Issue #181: analyzer-only references (first-party scope). -->.
Why nothing caught it. Two independent maskings:
- Local verification. The analyzer, nullable, and MSTest gates were run against PR Bump the analyzers-dev-deps group with 2 updates #573 and were green. They were green because a long-lived
packages/directory holdsMeziantou.Analyzer.3.0.101,3.0.123,3.0.156,3.0.174,Roslynator.Analyzers.4.16.0, and4.16.1from historical restores, so the stale paths resolve. A clean environment has only the two pinned versions. - CI.
.github/workflows/_build-analyzers.ymluseskey: nuget-${{ runner.os }}-${{ hashFiles('**/packages.config') }}withrestore-keys: nuget-${{ runner.os }}-. When the content-hash key misses - which is exactly what apackages.configbump causes - the prefix fallback restores an older cache containing the pre-bump packages, and the stale paths resolve. Green CI on apackages.configchange is therefore not evidence that a clean restore builds.
Logs / Screenshots
-
Attached minimal logs or screenshot
-
Snippet - the offending shape,
QuickFiler/QuickFiler.csproj:581-586:<!-- Issue #181: analyzer-only references (first-party scope). Severities are set to suggestion in .editorconfig so none break the nullable TreatWarningsAsErrors build. --> <Analyzer Include="..\packages\Meziantou.Analyzer.3.0.156\analyzers\dotnet\roslyn5.0\cs\Meziantou.Analyzer.dll" /> <Analyzer Include="..\packages\Roslynator.Analyzers.4.16.0\analyzers\dotnet\roslyn4.7\cs\Roslynator.CSharp.Analyzers.dll" /> <Analyzer Include="..\packages\Roslynator.Analyzers.4.16.0\analyzers\dotnet\roslyn4.7\cs\Roslynator_Analyzers_Roslynator.Common.dll" /> <Analyzer Include="..\packages\Roslynator.Analyzers.4.16.0\analyzers\dotnet\roslyn4.7\cs\Roslynator_Analyzers_Roslynator.Core.dll" /> <Analyzer Include="..\packages\Roslynator.Analyzers.4.16.0\analyzers\dotnet\roslyn4.7\cs\Roslynator_Analyzers_Roslynator.CSharp.dll" />
Impact / Severity
- Blocker
- High
- Medium
- Low
Blocker for onboarding and for any clean-environment build: a new clone, a fresh CI runner with a cold cache, or a developer who clears packages/ all hit error CS0006. It is not a blocker for the current working tree or for CI as presently configured, which is precisely why it has gone unnoticed since PR #573 merged. The severity reflects that the masking is incidental and can evaporate at any time - a cache eviction is enough.
Source
From: docs/features/potential/2026-08-23-csproj-analyzer-paths-stale-after-dependabot-bump-breaks-fresh-clone.md
Activity
docs(511): open remediation cycle 1; delete 1.2 GB of raw vstest output
docs(511): open remediation cycle 1; delete 1.2 GB of raw vstest output
docs(511): remediation cycle 1 - correct falsified claims, complete f…
docs(parallel): record item 637 worktree cleanup deferral
drmoisan commentedon Sep 2, 2026
Closing as completed. Delivered via PR #703 (commit
ece554d3, "(chore): update project references"), an ancestor of origin/main.Confirmed directly against origin/main: every first-party
packages.configpinsMeziantou.Analyzer 3.0.194andRoslynator.Analyzers 5.0.0, and a repo-wide scan of the hand-authored<Analyzer Include>items across all 16.csprojfiles that carry them shows exactly 16 lines citing3.0.194(Meziantou) and 64 lines citing5.0.0(Roslynator) — 80 lines total, zero lines citing any stale version. This is the same 16-file/80-line population the issue counted, now fully in sync rather than pointing at package folders a clean restore never creates.History confirms the drift and its resolution: commit
f8e22af7(dependabot bump 3.0.156→3.0.174) updated only the NuGet-managedImport/Errorguard lines, leaving the hand-authored<Analyzer Include>items stuck at3.0.156/4.16.0through several subsequent commits (matching the issue's exact snapshot atd15f9510). Commitece554d3brought the hand-authored items back into sync withpackages.config(at that point 3.0.194/5.0.0), eliminating the CS0006-on-clean-clone failure mode described in the issue.Verified during a full-repo bug sweep (2026-09-02). No branch or PR remains to ship; this was left open only as bookkeeping.