dotnet-stale-sdk-phantom-errors
Diagnose .NET builds where an IDE reports members that demonstrably exist in source ("X does not contain a definition for Y") alongside a "runtime.json / PortableRuntimeIdentifierGraph.json could not
SKILL.mdskills/managed/dotnet-stale-sdk-phantom-errors/SKILL.md
GitHubStale SDK under a running IDE
Symptom pair, reported together:
The runtime.json specified in the project 'C:\Program Files\dotnet\sdk\<VER>/PortableRuntimeIdentifierGraph.json' could not be found.
'SomeType' does not contain a definition for 'NewMember' ...
The member errors are downstream noise. Read the SDK error first: restore fails, so the referenced project never rebuilds, and the consuming project compiles against a stale DLL that genuinely lacks the new member. The source is usually fine.
Triage order
Confirm the source is innocent before touching anything:
git show HEAD:path/to/File.cs | grep -n "NewMember" git status --short # worktree clean? dotnet clean <consuming>.csproj && dotnet build <consuming>.csprojA clean CLI build with
0 errorsproves it is an environment fault.Distinguish missing from misinstalled. This decides the fix and is the step most likely to be skipped:
Test-Path 'C:/Program Files/dotnet/sdk/<VER>' Get-ChildItem 'C:/Program Files/dotnet/sdk' -Directory | % Name Get-ChildItem 'C:/Program Files/dotnet/sdk/<NEWVER>' -Filter '*RuntimeIdentifierGraph*'- Directory absent, and the newer SDK has both RID graph files intact
(
PortableRuntimeIdentifierGraph.json,RuntimeIdentifierGraph.json) → SDK was cleanly replaced. Nothing is corrupt. - Directory present but RID graph missing → genuinely misinstalled; repair/reinstall that SDK.
- Directory absent, and the newer SDK has both RID graph files intact
(
Check what pins the old version:
find . -maxdepth 2 -name global.json dotnet --version ; dotnet --list-sdksIf the CLI resolves the new SDK and there is no
global.json, nothing in the repo is pinning it — the stale path lives in a long-running process.Clear the stale processes:
dotnet build-server shutdown # does NOT clear VS-owned nodes Get-Process MSBuild,VBCSCompiler | Stop-Process -Force Get-Process devenv | Select Id,StartTimeCompare
devenvStartTime against the SDK upgrade. An IDE started before the upgrade resolved the SDK path at solution load and keeps using it no matter how many child nodes are killed.Fix: restart the IDE. Do not kill
devenvfor the user — unsaved state. Only if errors survive a restart:dotnet cleanat the repo root, sinceobj/may hold artifacts stamped with the old SDK path.
What NOT to do
- Do not clear NuGet/MSBuild caches reflexively. If step 2 shows the new SDK's RID graphs are intact, there is no corrupt cache; a wipe costs a full restore and fixes nothing.
- Do not reinstall the SDK when the directory is simply gone and a newer one is present and healthy.
- Do not trust the member errors as a code problem until step 1 says otherwise.
Prevention
Pin the SDK so a background upgrade cannot desync CLI from IDE:
{ "sdk": { "version": "10.0.401", "rollForward": "latestFeature" } }
Related
A different failure with similar-looking output: MSB3026/MSB3027/CS2012
file-lock errors mean a running app holds its own DLLs — stop the app, do
not read it as a compile error.