Skip to content

fix: warn when async client cleanup is skipped - #363

Open
abhinavkr26104 wants to merge 1 commit into
browserbase:mainfrom
abhinavkr26104:fix/356-async-client-cleanup
Open

fix: warn when async client cleanup is skipped#363
abhinavkr26104 wants to merge 1 commit into
browserbase:mainfrom
abhinavkr26104:fix/356-async-client-cleanup

Conversation

@abhinavkr26104

@abhinavkr26104 abhinavkr26104 commented Aug 15, 2026

Copy link
Copy Markdown

Summary

  • emit a ResourceWarning when an unclosed async HTTP client is collected without a running event loop
  • continue scheduling asynchronous cleanup when a loop is available
  • document explicit async with / await client.close() resource management
  • add warning and clean-close regression tests

Testing

Fixes #356


Summary by cubic

Warns when async async-client cleanup is skipped to prevent silent connection leaks. Previously AsyncHttpxClientWrapper.__del__ silently did nothing if no event loop was running; now it emits a ResourceWarning in that case and still schedules aclose() when a loop exists. README examples now use async with to show explicit lifecycle management, with tests covering both paths.

  • Migration
    • Use async with AsyncStagehand(...) or await client.close() to shut down async clients deterministically and avoid ResourceWarning.

Written for commit 87a7b03. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 3 files

Confidence score: 5/5

  • In tests/test_async_client_cleanup.py (test_unclosed_async_http_client_warns_without_running_loop), placing asyncio.run(client.aclose()) inside pytest.warns(...) means a failed warning assertion can skip cleanup, leaving an unclosed client that may cause noisy or flaky downstream tests — move cleanup to a finally block (or fixture finalizer) so it always runs.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/test_async_client_cleanup.py">

<violation number="1" location="tests/test_async_client_cleanup.py:17">
P3: In `test_unclosed_async_http_client_warns_without_running_loop`, the `asyncio.run(client.aclose())` cleanup runs only if the `pytest.warns(...)` block passes. If the expect-warning assertion fails (e.g. `__del__` stops warning), the block raises and the client is never closed, leaking an unclosed HTTP client into subsequent tests. Wrap the cleanup in a `try/finally` so the client is always closed deterministically.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

with pytest.warns(ResourceWarning, match="Unclosed async HTTP client"):
client.__del__()

asyncio.run(client.aclose())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: In test_unclosed_async_http_client_warns_without_running_loop, the asyncio.run(client.aclose()) cleanup runs only if the pytest.warns(...) block passes. If the expect-warning assertion fails (e.g. __del__ stops warning), the block raises and the client is never closed, leaking an unclosed HTTP client into subsequent tests. Wrap the cleanup in a try/finally so the client is always closed deterministically.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/test_async_client_cleanup.py, line 17:

<comment>In `test_unclosed_async_http_client_warns_without_running_loop`, the `asyncio.run(client.aclose())` cleanup runs only if the `pytest.warns(...)` block passes. If the expect-warning assertion fails (e.g. `__del__` stops warning), the block raises and the client is never closed, leaking an unclosed HTTP client into subsequent tests. Wrap the cleanup in a `try/finally` so the client is always closed deterministically.</comment>

<file context>
@@ -0,0 +1,28 @@
+    with pytest.warns(ResourceWarning, match="Unclosed async HTTP client"):
+        client.__del__()
+
+    asyncio.run(client.aclose())
+
+
</file context>

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Async client garbage collection silently skips connection cleanup without a running loop

1 participant