Skip to content

Fix System.Collections.Immutable binding mismatch in Common.dll (rel/18.5)#15720

Merged
nohwnd merged 2 commits intomicrosoft:rel/18.5from
nohwnd:repro-sci-dta-rel-18.5
Apr 23, 2026
Merged

Fix System.Collections.Immutable binding mismatch in Common.dll (rel/18.5)#15720
nohwnd merged 2 commits intomicrosoft:rel/18.5from
nohwnd:repro-sci-dta-rel-18.5

Conversation

@nohwnd
Copy link
Copy Markdown
Member

@nohwnd nohwnd commented Apr 22, 2026

Customer hit a System.Collections.Immutable FileLoadException on Azure DevOps' Distributed Test Agent (DTAExecutionHost) after it picked up Microsoft.TestPlatform 18.5.0. Root cause: Microsoft.VisualStudio.TestPlatform.Common.dll (net462) has a compiled metadata ref to SCI 8.0.0.0, but we ship SCI 9.0.0.0 right next to it in the package. Any host that doesn't have vstest.console.exe.config's 1.0.0.0-9.0.0.0 -> 9.0.0.0 binding redirect blows up as soon as FastFilter.Builder touches ImmutableDictionary.

Fix

Explicit <PackageReference Include="System.Collections.Immutable"> in CoreUtilities and ObjectModel, gated on TargetFrameworkIdentifier == .NETFramework. Only the net462 Common.dll gets the new SCI 9.0.0 compile ref - matching the DLL we already ship - and nothing else moves:

  • No change to app.config binding redirects anywhere.
  • netstandard2.0 Common.dll keeps SCI 8.0.0 so net8.0 datacollector (whose shared framework ships SCI 8.0.0) doesn't get MSB3277.
  • No change to the shipped SRM ref (still 8.0.0, matching its shipped DLL).
  • No VSIX or Visual Studio servicing needed.

Repro + automated regression guard

New DtaLikeHost test asset: minimal net472 exe, AutoGenerateBindingRedirects=false, references Common.dll by HintPath from the shipped layout and calls FilterExpressionWrapper (which triggers FastFilter.Builder). Without the fix it reproduces the customer's exact FileLoadException.

New DistributedTestAgentScenarioTests in acceptance tests runs the host in two layouts:

  1. tools/net462/Common7/IDE/Extensions/TestPlatform/ out of the locally-built Microsoft.TestPlatform nupkg (as DTA consumes it).
  2. Flat extracted Microsoft.VisualStudio.TestTools.TestPlatform.V2.CLI.vsix (as Visual Studio consumes it).

If any future change lets Common.dll's SCI/SRM compile refs drift away from the DLLs shipped next to it, both tests fail with the customer-visible error.

nohwnd and others added 2 commits April 22, 2026 22:37
Minimal net472 console app that consumes Microsoft.TestPlatform 18.5.0
package the way Azure DevOps' Distributed Test Agent does: references
Common.dll from the package's tools/net462/.../TestPlatform layout and runs
without any binding redirects in app.config.

Constructs a FilterExpressionWrapper with a simple equality filter, which
triggers FastFilter.Builder (uses ImmutableDictionary) and forces the CLR
to resolve System.Collections.Immutable.

Repros the FileLoadException reported by customers:
Common.dll metadata requires System.Collections.Immutable v8.0.0.0, but
the package ships v9.0.0.0 next to it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Common.dll (net462, shipped in the Microsoft.TestPlatform nupkg and the
V2.CLI VSIX) used to have a compiled metadata ref to
System.Collections.Immutable 8.0.0.0 while we ship SCI 9.0.0.0 next to it.
Hosts without the '1.0.0.0-9.0.0.0 -> 9.0.0.0' binding redirect
(Azure DevOps' DTAExecutionHost, some VS components) FileLoadException
the moment FastFilter.Builder touches SCI.

Fix: add an explicit System.Collections.Immutable PackageReference to
CoreUtilities and ObjectModel, gated on TargetFrameworkIdentifier ==
.NETFramework, so the compile-time SCI ref in the net462 Common.dll is
9.0.0. This only affects the net462 build (the one we ship next to SCI
9.0.0), keeps the netstandard2.0 ref on 8.0.0 to avoid breaking net8.0
datacollector, and touches zero app.config redirects - no VSIX/VS
servicing needed.

Turn the DtaLikeHost repro into an automated acceptance test with two
variants: one against the nupkg's tools/net462/... layout (as DTA
consumes it), one against the flat V2.CLI VSIX layout (as VS consumes
it). Both load Common.dll with no binding redirects and call
FilterExpressionWrapper; before the fix both fail with the customer's
FileLoadException.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nohwnd
Copy link
Copy Markdown
Member Author

nohwnd commented Apr 23, 2026

/azp run microsoft.vstest

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@nohwnd nohwnd merged commit bb8913d into microsoft:rel/18.5 Apr 23, 2026
2 of 5 checks passed
This was referenced Apr 28, 2026
This was referenced Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant