Version
1.60.0
Steps to reproduce
var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new() { Headless = true });
var page = await browser.NewPageAsync();
await page.SetContentAsync("<button id='b'>click</button>");
var handle = await page.QuerySelectorAsync("#b")
?? throw new InvalidOperationException("Selector returned null");
playwright.Dispose();
// System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Threading.SemaphoreSlim'.
await handle.DisposeAsync();
Expected behavior
Calling JSHandle.DisposeAsync on a handle whose Connection has already been disposed should either be a no-op or surface a typed Playwright exception such as TargetClosedException.
Actual behavior
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Threading.SemaphoreSlim'.
at System.Threading.SemaphoreSlim.WaitAsyncCore(Int64 millisecondsTimeout, CancellationToken cancellationToken)
at Microsoft.Playwright.Helpers.TaskQueue.EnqueueAsync(Func`1 taskGenerator) in /_/src/Playwright/Helpers/TaskQueue.cs:line 46
at Microsoft.Playwright.Transport.Connection.InnerSendMessageToServerAsync[T](ChannelOwner object, String method, Dictionary`2 dictionary, Boolean keepNulls) in /_/src/Playwright/Transport/Connection.cs:line 188
at Microsoft.Playwright.Transport.Connection.WrapApiCallAsync[T](Func`1 action, Boolean isInternal, String title) in /_/src/Playwright/Transport/Connection.cs:line 505
at Microsoft.Playwright.Core.JSHandle.DisposeAsync() in /_/src/Playwright/Core/JSHandle.cs:line 109
Additional context
No response
Environment
- Operating System: macOS 26.5.1
- CPU: arm64
- Browser: Chromium
- .NET Version (TFM): net10.0
Version
1.60.0
Steps to reproduce
Expected behavior
Calling
JSHandle.DisposeAsyncon a handle whose Connection has already been disposed should either be a no-op or surface a typed Playwright exception such asTargetClosedException.Actual behavior
Additional context
No response
Environment