Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710) - #9739

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test
Jul 8, 2026
Merged

Fix forward-compat crash loading old 2.x extensions on .NET Framework (#9710)#9739
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/improve-backcompat-acceptance-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Fixes#9710. A newer Microsoft.Testing.Platform combined with an older (2.x) extension crashes with MissingMethodException on .NET Framework:

Method not found: 'Void Polyfills.Polyfill.Deconstruct(...)'.
at Microsoft.Testing.Extensions.Telemetry.AppInsightsProvider.<IngestLoopAsync>d__18.MoveNext()

Root cause

Old 2.x extension assemblies (Telemetry, TrxReport, TrxReport.Abstractions, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helper, which they access from the platform assembly via [InternalsVisibleTo] (they don't embed their own copy). Their baked-in member references are resolved by the runtime against the platform assembly. Newer platform code stopped using those helpers, so they were dropped — and loading an old extension's netstandard2.0 / .NET Framework asset now throws. The .NET assets bind these to the BCL and are unaffected, which is why the original report crashed on net472 while net8.0 passed.

Fix

  • src/Polyfills/PolyfillBackwardCompatibility.cs — restore the exact Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync), guarded #if !NETCOREAPP so they land only in the netstandard2.0 platform asset (the one loaded on .NET Framework). The type is already internal with IVT to these extensions; [Embedded] only hides it from new compile-time references — the CLR still resolves old baked MemberRefs at runtime. A prominent comment warns against re-deleting them as "unused polyfills."

Test

  • TelemetryForwardCompatibilityTests — reproduces the crash: current platform + oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled (which is what forces AppInsightsProvider.IngestLoopAsync — the crashing method — to actually run). The existing ForwardCompatibilityTests missed this because it pinned 2.2.1 (no longer references the platform Polyfill) and ran telemetry opted out.

Verification (build.cmd -pack + acceptance run)

Notes for reviewers

  • The exact old-extension Polyfill surface was confirmed by decompiling the shipped 2.0.0netstandard2.0 nupkgs, so the shim covers every extension that referenced it (not just Telemetry). Happy to trim it to telemetry-only (Deconstruct) if preferred, but restoring the full set makes any old 2.x extension load correctly on .NET Framework.

…#9710)
A newer Microsoft.Testing.Platform combined with an older (2.x) extension whose
netstandard2.0 asset was compiled against the platform's internal Polyfills.Polyfill
helper (shared via InternalsVisibleTo) threw MissingMethodException in
AppInsightsProvider.IngestLoopAsync on .NET Framework, crashing the process.
- Restore the exact Polyfills.Polyfill members old 2.x extensions reference
(Deconstruct, Contains x2, AppendJoin x2, CopyToAsync, SaveAsync), guarded to the
non-.NET-Core TFMs so they land only in the netstandard2.0 platform asset that is
loaded on .NET Framework. The type is already internal with IVT to the extensions;
[Embedded] only hides it from new compile-time references, so the CLR still resolves
old baked MemberRefs at runtime.
- Add TelemetryForwardCompatibilityTests reproducing the crash: current platform +
oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Verified red without the shim (exit code -532462766) and green with it.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings July 8, 2026 14:36
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #9739

GradeTestNotes
A (90–100)new TelemetryForwardCompatibilityTests.
NewerPlatform_
WithOldestSupportedTelemetryExtension_
TelemetryEnabled_
OnNetFramework_
ShouldNotCrash
Clear AAA structure; three complementary assertions cover exit code, summary, and regression-specific failure mode.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Re-run with
/grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · 46.3 AIC · ⌖ 6.97 AIC · ⊞ 9.5K · [◷]( · )

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes #9710, where a newer Microsoft.Testing.Platform crashes with MissingMethodException on .NET Framework when loading an older (2.x) extension. Old 2.x extension assemblies (Telemetry, TrxReport, VSTestBridge) were compiled against the platform's internal Polyfills.Polyfill helpers and resolve those MemberRefs from the platform assembly at runtime via [InternalsVisibleTo]. Newer platform code stopped using those helpers, so they were dropped — breaking the netstandard2.0 load path. The fix restores the exact member set, guarded to the non-netcore asset, and adds a regression test.

Changes:

  • Restore the Polyfills.Polyfill members old 2.x extensions reference (Deconstruct, Contains×2, AppendJoin×2, CopyToAsync, SaveAsync) in a new #if !NETCOREAPP file, with a prominent comment warning against re-deleting them as "unused."
  • Add TelemetryForwardCompatibilityTests reproducing the crash with the oldest supported 2.x telemetry extension (2.0.0) on net462 with telemetry enabled.
Show a summary per file
FileDescription
src/Polyfills/PolyfillBackwardCompatibility.csNew netstandard2.0/.NET Framework-only file restoring the internal Polyfill members old 2.x extensions bind to at runtime, preventing MissingMethodException.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryForwardCompatibilityTests.csNew acceptance test reproducing #9710 (newest platform + oldest 2.x telemetry extension on net462, telemetry enabled) and guarding against regression.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Medium

@github-actionsgithub-actionsBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 15/15 dimensions clean — no findings.

DimensionSeverityVerdict
Algorithmic CorrectnessMAJORLGTM
Threading & ConcurrencyBLOCKINGLGTM
Public API & Binary CompatibilityBLOCKINGLGTM
Cross-TFM CompatibilityMAJORLGTM
Defensive CodingMAJORLGTM
Flakiness PatternsBLOCKINGLGTM
Test IsolationMAJORLGTM
Assertion QualityMAJORLGTM
Test Completeness & CoverageMAJORLGTM
Code Structure & SimplificationMODERATELGTM
Naming & ConventionsNITLGTM
Documentation AccuracyNITLGTM
Performance & AllocationsMAJORLGTM
Resource & IDisposable ManagementMAJORLGTM
Scope & PR DisciplineMODERATELGTM

Summary: Clean, well-scoped fix. The polyfill implementations are correct and binary-compatible with old 2.x extension MemberRef tokens. The #if !NETCOREAPP guard correctly targets the netstandard2.0 build (which is what .NET Framework loads). The acceptance test faithfully reproduces the crash conditions (net462 + telemetry enabled + oldest 2.x extension) and the IMPORTANT comment provides strong protection against future accidental removal.

@Evangelink

Copy link
Copy Markdown
MemberAuthor

/backport to rel/4.3

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/28952108089

Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
New 2.3.1 UNRELEASED servicing section for the .NET Framework MissingMethodException regression (#9710) fixed by #9739, being backported to rel/4.3 via #9740.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) July 8, 2026 15:27
@EvangelinkAmaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Jul 8, 2026
@Evangelink
Amaury Levé (Evangelink) merged commit dff367b into mainJul 8, 2026
37 of 41 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/improve-backcompat-acceptance-test branch July 8, 2026 16:45
Amaury Levé (Evangelink) added a commit that referenced this pull request Jul 8, 2026
…#9710) by @Evangelink in #9739 (backport to rel/4.3) (#9740)
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-reviewAwaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.MissingMethodException after upgrade to 2.3.0

3 participants

@Evangelink@0101