Skip to content

[8.0-preview.5] Possible Issue with AsyncLocal<T>/TaskCreationOptions.RunContinuationsAsynchronously #87628

Description

@martincostello

Description

I have a number of applications that were targeting .NET 8 preview 4 that have been upgraded to .NET preview 5 this week. In four different applications (only 3 are public), I've observed issues with their UI tests that use Microsoft.Playwright where a NullReferenceException is thrown from within the Playwright code during test execution.

These failures occur on Windows, macOS and Linux, but exactly what fails seems to vary slightly between the different applications and operating systems.

After doing various investigation, including debugging one of the applications consuming Microsoft.Playwright from source, I wonder if there's an issue somewhere related to AsyncLocal<T> and/or TaskCreationOptions.RunContinuationsAsynchronously in .NET 8 preview 5? This is partly just a hunch as I've seen PRs into the repo recently around Task-related refactoring, I might be way off in my assessment.

The code for the relevant parts of Playwright in v1.35.0 using these are here:

When referencing the Playwright code from source I added the following lines before the AsyncLocal<T> is accessed:

if (ApiZone is null)
{
    throw new InvalidOperationException("ApiZone is null.");
}
if (ApiZone.Value is null)
{
    throw new InvalidOperationException("ApiZone.Value is null.");
}
if (ApiZone.Value[0] is null)
{
    throw new InvalidOperationException("ApiZone.Value[0] is null.");
}

Re-running the tests with this edit changes the test failures to the following:

  Error Message:
   System.InvalidOperationException : ApiZone.Value[0] is null.
  Stack Trace:
     at Microsoft.Playwright.Transport.Connection.InnerSendMessageToServerAsync[T](String guid, String method, Dictionary`2 dictionary, Boolean keepNulls) in C:\Coding\microsoft\playwright-dotnet\src\Playwright\Transport\Connection.cs:line 161

This seems to suggest to me that the try-catch which is editing ApiZone.Value[0] is not running in the execution order that is expected by the async calls. This is just my inference though at trying to explain away the exception - I'm not familiar with the inner workings of Playwright's implementation.

Observing the UI tests with headless mode disabled (as well as reviewing screenshots and recordings) don't seem to suggest any issues with the applications themselves in terms of their expected behaviour (i.e. genuine test failures), it seems that something is just causing Playwright to fail internally.

An additional factor to me thinking this is something related to AsyncLocal<T> is that if I run an affected test which is data-driven and remove all of the browser combinations and just run a single browser (whatever that browser is), then the test passed on each of my attempts. Similarly, the same test may fail on different lines during the assertions, rather than always the exact same failure.

Reproduction Steps

  1. Clone martincostello/dependabot-helper@6006968
  2. Run build.ps1 -TestFilter Can_Configure_Repositories

Expected behavior

The tests pass.

Actual behavior

One or more tests fail with an exception similar to the below:

  Failed MartinCostello.DependabotHelper.UITests.Can_Configure_Repositories(browserType: "firefox", browserChannel: null) [6 s]
  Error Message:
   System.NullReferenceException : Object reference not set to an instance of an object.
  Stack Trace:
     at Microsoft.Playwright.Transport.Connection.InnerSendMessageToServerAsync[T](String guid, String method, Dictionary`2 dictionary, Boolean keepNulls) in /_/src/Playwright/Transport/Connection.cs:line 150
   at Microsoft.Playwright.Transport.Connection.WrapApiCallAsync[T](Func`1 action, Boolean isInternal)
   at Microsoft.Playwright.Core.ElementHandle.QuerySelectorAsync(String selector) in /_/src/Playwright/Core/ElementHandle.cs:line 181
   at MartinCostello.DependabotHelper.Pages.ConfigurePage.RepositoryItem.IsSelectedAsync() in /_/tests/DependabotHelper.Tests/Pages/ConfigurePage.cs:line 141
   at Shouldly.ShouldlyTaskExtensions.ShouldBeFalse(Task`1 task) in /_/tests/DependabotHelper.Tests/Infrastructure/ShouldlyTaskExtensions.cs:line 22
   at MartinCostello.DependabotHelper.UITests.<>c__DisplayClass5_0.<<Can_Configure_Repositories>b__0>d.MoveNext() in /_/tests/DependabotHelper.Tests/UITests.cs:line 166
--- End of stack trace from previous location ---
   at MartinCostello.DependabotHelper.Infrastructure.BrowserFixture.WithPageAsync(Func`2 action, String testName) in /_/tests/DependabotHelper.Tests/Infrastructure/BrowserFixture.cs:line 59
   at MartinCostello.DependabotHelper.Infrastructure.BrowserFixture.WithPageAsync(Func`2 action, String testName) in /_/tests/DependabotHelper.Tests/Infrastructure/BrowserFixture.cs:line 64
   at MartinCostello.DependabotHelper.Infrastructure.BrowserFixture.WithPageAsync(Func`2 action, String testName) in /_/tests/DependabotHelper.Tests/Infrastructure/BrowserFixture.cs:line 76
   at MartinCostello.DependabotHelper.Infrastructure.BrowserFixture.WithPageAsync(Func`2 action, String testName) in /_/tests/DependabotHelper.Tests/Infrastructure/BrowserFixture.cs:line 76
   at MartinCostello.DependabotHelper.Infrastructure.BrowserFixture.WithPageAsync(Func`2 action, String testName) in /_/tests/DependabotHelper.Tests/Infrastructure/BrowserFixture.cs:line 76
   at MartinCostello.DependabotHelper.UITests.Can_Configure_Repositories(String browserType, String browserChannel) in /_/tests/DependabotHelper.Tests/UITests.cs:line 126

Regression?

Yes. The test pass with .NET 7.0.7 and with .NET 8 preview 4.

Known Workarounds

None.

Configuration

  • .NET SDK 8.0.100-preview.5.23303.2
  • Observed on Windows, Linux and macOS GitHub Actions runners as well as locally with Windows 11.

Other information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Priority:1Work that is critical for the release, but we could probably ship withoutarea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItracking-external-issueThe issue is caused by external problem (e.g. OS) - nothing we can do to fix it directly

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions