Summary
The artifacts-helper feature installs a dotnet shell-script wrapper at /usr/local/share/codespace-shims/dotnet and prepends that directory to PATH (via /etc/environment and a dotnet() bash function in ~/.bashrc).
This breaks the C# Dev Kit's Test Explorer in vscode. In the Test Explorer UI, the test projects' assemblies are listed but no tests appear under them, and attempting to run a test fails immediately with this message in the test window:
The test run did not record any output.
The "C# Dev Kit - Test Explorer" output channel shows a one-time initialization failure that cascades into every discovery/run operation:
[error] Initialization failed: Failed to find all versions of .NET Core MSBuild. Call to {0}. There may be more details in stderr.
[error] Test runner is not initialized. Call InitializeAsync first.
Environment
- Base image:
mcr.microsoft.com/devcontainers/dotnet:2-10.0-noble (Ubuntu 24.04, x64)
- Feature:
ghcr.io/microsoft/codespace-features/artifacts-helper:latest
- .NET SDK 10.0.301, single SDK, installed at
/usr/share/dotnet, no global.json
- C# Dev Kit 3.20.199
Possible root cause
The Test Explorer appears to use MSBuild to discover and run tests. To locate the MSBuild it needs, it searches for the first dotnet executable on PATH, then uses the directory that dotnet sits in to find MSBuild relative to it (i.e. <dir>/host/fxr/... and <dir>/sdk/...).
When the artifacts-helper feature is installed in a dev container, its shim becomes the first dotnet on PATH — but the shim's parent directory (/usr/local/share/codespace-shims) does not contain the host/ and sdk/ directory structure that MSBuild is located under. So the relative lookup fails.
The ServiceHost log confirms this — it can't find the hostfxr library that lives under host/fxr:
Beginning to attempt to load unmanaged assembly 'hostfxr'.
Could not resolve 'hostfxr' using the AssemblyDependencyResolver.
Deferring to the default Core CLR policy of loading unmanaged assemblies.
Notably, the C# Dev Kit language server works fine (it honors DOTNET_ROOT/the existingDotnetPath setting), but the Test Explorer ServiceHost ignores DOTNET_ROOT for this resolution and keys off the dotnet location on PATH — so the shim is what surfaces the break.
The relative-search behavior, demonstrated
The .NET host resolves the SDK relative to its own directory — exactly what hostfxr_resolve_sdk2 does. With a real dotnet host and nothing beside it:
$ cp /usr/share/dotnet/dotnet /tmp/fakeroot/dotnet
$ /tmp/fakeroot/dotnet --list-sdks
Error: [/tmp/fakeroot/host/fxr] does not exist # looks relative to its own dir
$ ln -s /usr/share/dotnet/{host,sdk,shared} /tmp/fakeroot/
$ /tmp/fakeroot/dotnet --list-sdks
10.0.301 [/tmp/fakeroot/sdk] # now resolves
Since the shim directory has neither host/ nor sdk/, any consumer that resolves the SDK relative to the dotnet it finds on PATH fails there.
Minimal reproduction
- Dev container from
mcr.microsoft.com/devcontainers/dotnet:2-10.0-noble with the artifacts-helper feature enabled.
- Open a workspace with a .NET test project and the C# Dev Kit extension.
- Open the Test Explorer → projects appear but no tests; running a test reports "The test run did not record any output," and the log shows the error above.
Workaround (what we're using)
Set DOTNET_HOST_PATH (and DOTNET_ROOT) in devcontainer.json so resolution roots at the real install rather than the shim dir:
This is purely additive — it does not change PATH or disable the shim, so the feature's AzDO credential injection for terminal/CLI dotnet and nuget restores is unaffected.
Summary
The
artifacts-helperfeature installs adotnetshell-script wrapper at/usr/local/share/codespace-shims/dotnetand prepends that directory toPATH(via/etc/environmentand adotnet()bash function in~/.bashrc).This breaks the C# Dev Kit's Test Explorer in vscode. In the Test Explorer UI, the test projects' assemblies are listed but no tests appear under them, and attempting to run a test fails immediately with this message in the test window:
The "C# Dev Kit - Test Explorer" output channel shows a one-time initialization failure that cascades into every discovery/run operation:
Environment
mcr.microsoft.com/devcontainers/dotnet:2-10.0-noble(Ubuntu 24.04, x64)ghcr.io/microsoft/codespace-features/artifacts-helper:latest/usr/share/dotnet, noglobal.jsonPossible root cause
The Test Explorer appears to use MSBuild to discover and run tests. To locate the MSBuild it needs, it searches for the first
dotnetexecutable onPATH, then uses the directory thatdotnetsits in to find MSBuild relative to it (i.e.<dir>/host/fxr/...and<dir>/sdk/...).When the
artifacts-helperfeature is installed in a dev container, its shim becomes the firstdotnetonPATH— but the shim's parent directory (/usr/local/share/codespace-shims) does not contain thehost/andsdk/directory structure that MSBuild is located under. So the relative lookup fails.The ServiceHost log confirms this — it can't find the
hostfxrlibrary that lives underhost/fxr:Notably, the C# Dev Kit language server works fine (it honors
DOTNET_ROOT/theexistingDotnetPathsetting), but the Test Explorer ServiceHost ignoresDOTNET_ROOTfor this resolution and keys off thedotnetlocation onPATH— so the shim is what surfaces the break.The relative-search behavior, demonstrated
The .NET host resolves the SDK relative to its own directory — exactly what
hostfxr_resolve_sdk2does. With a realdotnethost and nothing beside it:Since the shim directory has neither
host/norsdk/, any consumer that resolves the SDK relative to thedotnetit finds onPATHfails there.Minimal reproduction
mcr.microsoft.com/devcontainers/dotnet:2-10.0-noblewith theartifacts-helperfeature enabled.Workaround (what we're using)
Set
DOTNET_HOST_PATH(andDOTNET_ROOT) indevcontainer.jsonso resolution roots at the real install rather than the shim dir:This is purely additive — it does not change
PATHor disable the shim, so the feature's AzDO credential injection for terminal/CLIdotnetandnugetrestores is unaffected.