Skip to content

Conversation

@cubic-dev-local
Copy link

Summary by cubic

Add cloud_browser support to run agents on the Browser-Use Cloud. It provisions a cloud browser on demand, connects via CDP, and cleans up sessions automatically.

  • New Features

    • Browser(cloud_browser=True) to auto-provision a cloud browser via a new CloudBrowserClient (auth via BROWSER_USE_API_KEY or saved config).
    • BrowserSession uses the cloud CDP URL on start and cleans up the session on stop.
    • New example (examples/browser/cloud_browser.py) and docs/README updates with usage.
    • CI tests cover create/stop/auth flows; default model moved to gpt-4.1-mini and templates/tokenization updated.
  • Migration

    • To use the cloud: set BROWSER_USE_API_KEY and pass Browser(cloud_browser=True).
    • No changes needed for local browsers.
---

Based on: browser-use/browser-use#3139

sauravpanda and others added 5 commits September 16, 2025 22:27
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Copy link

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

Choose a reason for hiding this comment

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

13 issues found across 10 files

Prompt for AI agents (all 13 issues)

Understand the root cause of the following 13 issues and fix them.


<file name="examples/browser/cloud_browser.py">

<violation number="1" location="examples/browser/cloud_browser.py:20">
Tabs used for indentation; prefer 4 spaces per PEP 8 to avoid mixing issues and ensure consistent formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Style-only. Tabs are valid if used consistently; no mixing observed and no functional impact.</violation>

<violation number="2" location="examples/browser/cloud_browser.py:36">
Case-sensitive error check may miss authentication errors; normalize case for robust matching.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Trivial hint-only improvement in an example; case sensitivity doesn’t affect functionality or error reporting.</violation>
</file>

<file name="browser_use/dom/playground/extraction.py">

<violation number="1" location="browser_use/dom/playground/extraction.py:178">
encoding_for_model can raise KeyError if &#39;gpt-4.1-mini&#39; isn’t recognized by the installed tiktoken. Add a safe fallback (e.g., get_encoding) to avoid runtime errors.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:31">
Grammar: &quot;We ship every day improvements&quot; is awkward; prefer &quot;We ship improvements every day&quot; or &quot;We ship daily improvements&quot; for clarity.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.*</violation>

<violation number="2" location="README.md:89">
Grammar/style: Use &quot;First, set the `BROWSER_USE_API_KEY` environment variable&quot; (lowercase verb, add article, and format env var).

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity.*</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:121">
Cloud browser cleanup failures are silenced by a broad `try...except` block that logs errors at the `debug` level. This hides critical failures during session termination, such as network errors or API failures, which can lead to orphaned cloud resources and unexpected costs for the user.</violation>

<violation number="2" location="browser_use/browser/cloud.py:227">
The use of a global singleton for `CloudBrowserClient` prevents concurrent cloud browser sessions. The `_cloud_client` holds state like `current_session_id`, and when multiple agents run concurrently, they overwrite this shared state, causing one agent&#39;s cleanup to terminate another&#39;s browser and leaving the original browser orphaned.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:509">
After cleaning up a cloud session, cdp_url is not cleared, leaving a stale CDP URL that may cause reconnect attempts to fail on next start. Consider clearing browser_profile.cdp_url for cloud sessions on stop.</violation>

<violation number="2" location="browser_use/browser/session.py:517">
Re-raising CloudBrowserAuthError with a new instance drops the original traceback. Prefer a bare raise to preserve context or chain with `from e`.</violation>

<violation number="3" location="browser_use/browser/session.py:521">
Wraps CloudBrowserError without exception chaining, losing original cause. Use exception chaining to preserve context.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:250">
Patching an async function without AsyncMock produces a non-awaitable MagicMock; use new_callable=AsyncMock to properly mock the coroutine.</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:293">
Patch async functions with AsyncMock to ensure the patched callable is awaitable and consistent with coroutine behavior.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Side effect raises immediately; awaitability of the mock is irrelevant here. Low impact.</violation>

<violation number="3" location="tests/ci/test_cloud_browser.py:294">
Side-effect error message does not match the subsequent assertion; align the message so the assertion passes.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.



async def main():
"""Basic cloud browser example."""
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Tabs used for indentation; prefer 4 spaces per PEP 8 to avoid mixing issues and ensure consistent formatting.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Style-only. Tabs are valid if used consistently; no mixing observed and no functional impact.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 20:

<comment>Tabs used for indentation; prefer 4 spaces per PEP 8 to avoid mixing issues and ensure consistent formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Style-only. Tabs are valid if used consistently; no mixing observed and no functional impact.</comment>

<file context>
@@ -0,0 +1,41 @@
+
+
+async def main():
+	&quot;&quot;&quot;Basic cloud browser example.&quot;&quot;&quot;
+
+	print(&#39;🌤️ Using Browser-Use Cloud Browser&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

print(f'✅ Result: {result}')
except Exception as e:
print(f'❌ Error: {e}')
if 'Authentication' in str(e):
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Case-sensitive error check may miss authentication errors; normalize case for robust matching.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Trivial hint-only improvement in an example; case sensitivity doesn’t affect functionality or error reporting.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 36:

<comment>Case-sensitive error check may miss authentication errors; normalize case for robust matching.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Trivial hint-only improvement in an example; case sensitivity doesn’t affect functionality or error reporting.</comment>

<file context>
@@ -0,0 +1,41 @@
+		print(f&#39;✅ Result: {result}&#39;)
+	except Exception as e:
+		print(f&#39;❌ Error: {e}&#39;)
+		if &#39;Authentication&#39; in str(e):
+			print(&#39;💡 Set BROWSER_USE_API_KEY environment variable&#39;)
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

# pyperclip.copy(text_to_save)

encoding = tiktoken.encoding_for_model('gpt-4o')
encoding = tiktoken.encoding_for_model('gpt-4.1-mini')
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

encoding_for_model can raise KeyError if 'gpt-4.1-mini' isn’t recognized by the installed tiktoken. Add a safe fallback (e.g., get_encoding) to avoid runtime errors.

Prompt for AI agents
Address the following comment on browser_use/dom/playground/extraction.py at line 178:

<comment>encoding_for_model can raise KeyError if &#39;gpt-4.1-mini&#39; isn’t recognized by the installed tiktoken. Add a safe fallback (e.g., get_encoding) to avoid runtime errors.</comment>

<file context>
@@ -175,7 +175,7 @@ def get_website_list_for_prompt() -&gt; str:
 				# pyperclip.copy(text_to_save)
 
-				encoding = tiktoken.encoding_for_model(&#39;gpt-4o&#39;)
+				encoding = tiktoken.encoding_for_model(&#39;gpt-4.1-mini&#39;)
 				token_count = len(encoding.encode(text_to_save))
 				print(f&#39;Token count: {token_count}&#39;)
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Grammar/style: Use "First, set the BROWSER_USE_API_KEY environment variable" (lowercase verb, add article, and format env var).

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity.

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>Grammar/style: Use &quot;First, set the `BROWSER_USE_API_KEY` environment variable&quot; (lowercase verb, add article, and format env var).

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity.*</comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First, set the `BROWSER_USE_API_KEY` environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Fix with Cubic

**🚀 Use the latest version!**

> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Grammar: "We ship every day improvements" is awkward; prefer "We ship improvements every day" or "We ship daily improvements" for clarity.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.

Prompt for AI agents
Address the following comment on README.md at line 31:

<comment>Grammar: &quot;We ship every day improvements&quot; is awkward; prefer &quot;We ship improvements every day&quot; or &quot;We ship daily improvements&quot; for clarity.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.*</comment>

<file context>
@@ -15,20 +15,20 @@
+**🚀 Use the latest version!**
 
-&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**. 
+&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**.
 &gt; ```bash
 &gt; uv pip install --upgrade browser-use
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship improvements every day for **speed**, **accuracy**, and **UX**.
Fix with Cubic

'Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable'
)
except CloudBrowserError as e:
raise CloudBrowserError(f'Failed to create cloud browser: {e}')
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Wraps CloudBrowserError without exception chaining, losing original cause. Use exception chaining to preserve context.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 521:

<comment>Wraps CloudBrowserError without exception chaining, losing original cause. Use exception chaining to preserve context.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+							&#39;Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable&#39;
+						)
+					except CloudBrowserError as e:
+						raise CloudBrowserError(f&#39;Failed to create cloud browser: {e}&#39;)
+				elif self.is_local:
 					# Launch local browser using event-driven approach
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
raise CloudBrowserError(f'Failed to create cloud browser: {e}')
raise CloudBrowserError(f'Failed to create cloud browser: {e}') from e
Fix with Cubic

self.browser_profile.is_local = False
self.logger.info('🌤️ Successfully connected to cloud browser service')
except CloudBrowserAuthError:
raise CloudBrowserAuthError(
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Re-raising CloudBrowserAuthError with a new instance drops the original traceback. Prefer a bare raise to preserve context or chain with from e.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 517:

<comment>Re-raising CloudBrowserAuthError with a new instance drops the original traceback. Prefer a bare raise to preserve context or chain with `from e`.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+						self.browser_profile.is_local = False
+						self.logger.info(&#39;🌤️ Successfully connected to cloud browser service&#39;)
+					except CloudBrowserAuthError:
+						raise CloudBrowserAuthError(
+							&#39;Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable&#39;
+						)
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic


# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
mock_cloud_cdp.side_effect = CloudBrowserAuthError('No auth token')
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Side-effect error message does not match the subsequent assertion; align the message so the assertion passes.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 294:

<comment>Side-effect error message does not match the subsequent assertion; align the message so the assertion passes.</comment>

<file context>
@@ -0,0 +1,333 @@
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
+		# Verify that the cloud browser client raises the expected error
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
mock_cloud_cdp.side_effect = CloudBrowserAuthError('No auth token')
mock_cloud_cdp.side_effect = CloudBrowserAuthError('BROWSER_USE_API_KEY environment variable')
Fix with Cubic

profile = BrowserProfile(cloud_browser=True)

# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Patch async functions with AsyncMock to ensure the patched callable is awaitable and consistent with coroutine behavior.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Side effect raises immediately; awaitability of the mock is irrelevant here. Low impact.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 293:

<comment>Patch async functions with AsyncMock to ensure the patched callable is awaitable and consistent with coroutine behavior.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Side effect raises immediately; awaitability of the mock is irrelevant here. Low impact.</comment>

<file context>
@@ -0,0 +1,333 @@
+	profile = BrowserProfile(cloud_browser=True)
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

assert session.cloud_browser is True

# Test that get_cloud_browser_cdp_url works with mocked API
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 18, 2025

Choose a reason for hiding this comment

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

Patching an async function without AsyncMock produces a non-awaitable MagicMock; use new_callable=AsyncMock to properly mock the coroutine.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 250:

<comment>Patching an async function without AsyncMock produces a non-awaitable MagicMock; use new_callable=AsyncMock to properly mock the coroutine.</comment>

<file context>
@@ -0,0 +1,333 @@
+		assert session.cloud_browser is True
+
+		# Test that get_cloud_browser_cdp_url works with mocked API
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

34 issues found across 10 files

Prompt for AI agents (all 34 issues)

Understand the root cause of the following 34 issues and fix them.


<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:64">
two-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method. 

• **Libraries consulted**:</violation>

<violation number="2" location="browser_use/browser/cloud.py:64">
single-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method. 

• **Libraries consulted**:</violation>

<violation number="3" location="browser_use/browser/cloud.py:105">
two-agent-filter: stop_browser assumes JSON body and full schema; 204 or partial JSON causes exceptions and leaks cleanup

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Speculative; project tests expect 200 OK with full JSON for stop. No evidence of 204/partial responses. Implementation matches tested behavior.</violation>

<violation number="4" location="browser_use/browser/cloud.py:105">
single-agent-filter: stop_browser assumes JSON body and full schema; 204 or partial JSON causes exceptions and leaks cleanup

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Speculative. The claim hinges on the cloud API returning 204 or partial JSON, which is not evidenced. If the API consistently returns a full JSON resource on success (common for PATCH), response.json() and the Pydantic model are correct. Without documentation proof, the failure scenario is uncertain; filter to avoid a false positive.</violation>

<violation number="5" location="browser_use/browser/cloud.py:112">
single-agent-filter: Avoid logging the full CDP URL; it may contain sensitive tokens. Log a sanitized message or omit the value. 

• **Libraries consulted**:</violation>

<violation number="6" location="browser_use/browser/cloud.py:112">
two-agent-filter: Avoid logging the full CDP URL; it may contain sensitive tokens. Log a sanitized message or omit the value. 

• **Libraries consulted**:</violation>

<violation number="7" location="browser_use/browser/cloud.py:113">
single-agent-filter: Avoid logging the full live URL; log a generic message or sanitize sensitive parts.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Redundant/less severe compared to CDP URL. Evidence of sensitive content is weaker and overlaps with violation 0; keep the more critical issue only.</violation>

<violation number="8" location="browser_use/browser/cloud.py:113">
two-agent-filter: Avoid logging the full live URL; log a generic message or sanitize sensitive parts.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Logging the live URL may reveal an endpoint but lacks clear evidence of sensitive data. Debug-only and potentially non-secret; impact is speculative. To minimize false positives, do not report.</violation>

<violation number="9" location="browser_use/browser/cloud.py:227">
two-agent-filter: Global mutable client in async context risks race conditions and state leaks; prefer per-session instances or a concurrency-safe manager.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Using a global async client may present concurrency risks, but no concrete bug is demonstrated. httpx.AsyncClient supports concurrent use, and the module may be intended for a single session. The claim is speculative without broader context.</violation>

<violation number="10" location="browser_use/browser/cloud.py:227">
single-agent-filter: Global mutable client in async context risks race conditions and state leaks; prefer per-session instances or a concurrency-safe manager. 

• **Libraries consulted**:</violation>

<violation number="11" location="browser_use/browser/cloud.py:243">
two-agent-filter: Global CloudBrowserClient causes race conditions, client closing during concurrent use, and session leaks 

• **Libraries consulted**:</violation>

<violation number="12" location="browser_use/browser/cloud.py:243">
single-agent-filter: Global CloudBrowserClient causes race conditions, client closing during concurrent use, and session leaks 

• **Libraries consulted**:</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:89">
two-agent-filter: Grammar/style: use sentence case and add comma after &quot;First&quot;.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Minor grammatical/style issue in README. No functional impact; low importance. Filter out.</violation>

<violation number="2" location="README.md:89">
single-agent-filter: Grammar/style: use sentence case and add comma after &quot;First&quot;.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.* 

• **Libraries consulted**:</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:18">
two-agent-filter: The global state management for cloud sessions is architecturally flawed. Using a single global client in `cloud.py` to manage multiple independent `BrowserSession` instances from `session.py` will cause resource leaks. The system can only track the last created browser, so stopping one session will incorrectly terminate another, and earlier sessions will be orphaned. 

• **Libraries consulted**:</violation>

<violation number="2" location="browser_use/browser/session.py:18">
single-agent-filter: The global state management for cloud sessions is architecturally flawed. Using a single global client in `cloud.py` to manage multiple independent `BrowserSession` instances from `session.py` will cause resource leaks. The system can only track the last created browser, so stopping one session will incorrectly terminate another, and earlier sessions will be orphaned. 

• **Libraries consulted**:</violation>

<violation number="3" location="browser_use/browser/session.py:509">
two-agent-filter: Use the newly added cloud_browser property for consistency with other convenience properties.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #2; stylistic consistency only, negligible impact.</violation>

<violation number="4" location="browser_use/browser/session.py:509">
two-agent-filter: Use the newly added cloud_browser property for consistency with other convenience properties.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Style-only (property vs direct field); no functional impact or significant maintainability concern.</violation>

<violation number="5" location="browser_use/browser/session.py:509">
single-agent-filter: Use the newly added cloud_browser property for consistency with other convenience properties.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #2: using the profile field directly is equivalent to the property here; no functional or maintainability risk beyond style.</violation>

<violation number="6" location="browser_use/browser/session.py:509">
single-agent-filter: Use the newly added cloud_browser property for consistency with other convenience properties.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accessing self.browser_profile.cloud_browser is functionally identical to the convenience property. This is a stylistic consistency suggestion with no functional impact.</violation>

<violation number="7" location="browser_use/browser/session.py:517">
two-agent-filter: Preserve original CloudBrowserAuthError cause to retain traceback (use `except CloudBrowserAuthError as e:` and `raise ... from e`). 

• **Libraries consulted**:</violation>

<violation number="8" location="browser_use/browser/session.py:517">
single-agent-filter: Preserve original CloudBrowserAuthError cause to retain traceback (use `except CloudBrowserAuthError as e:` and `raise ... from e`).

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Even without capturing as e, raising a new exception within an except block keeps the original as __context__. The impact is minimal and largely stylistic.</violation>

<violation number="9" location="browser_use/browser/session.py:521">
two-agent-filter: Preserve original exception context when re-raising to aid debugging by using exception chaining (raise ... from e). 

• **Libraries consulted**:</violation>

<violation number="10" location="browser_use/browser/session.py:521">
single-agent-filter: Preserve original exception context when re-raising to aid debugging by using exception chaining (raise ... from e).

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Raising a new exception inside an except block preserves the original exception as __context__ by default in Python; the traceback isn’t lost. This is a minor debugging/style improvement, not a high-impact bug.</violation>
</file>

<file name="examples/browser/cloud_browser.py">

<violation number="1" location="examples/browser/cloud_browser.py:34">
two-agent-filter: Avoid catching broad Exception; catch specific exceptions to prevent masking errors and enable targeted handling.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Example script; broad Exception catch used for user-friendly messaging with low impact. Not worth reporting.</violation>

<violation number="2" location="examples/browser/cloud_browser.py:34">
single-agent-filter: Avoid catching broad Exception; catch specific exceptions to prevent masking errors and enable targeted handling.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Technically true but low-impact in an example script; broad catch is used to provide a simple user hint. Suggesting specific exceptions here is stylistic and not critical. Per criteria, error-handling changes should be avoided unless preventing critical failure.</violation>

<violation number="3" location="examples/browser/cloud_browser.py:36">
two-agent-filter: The string check for &#39;Authentication&#39; is case-sensitive and brittle; use a case-insensitive match to avoid missing variations.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Case-sensitive check affects only an optional hint; negligible impact.</violation>

<violation number="4" location="examples/browser/cloud_browser.py:36">
single-agent-filter: The string check for &#39;Authentication&#39; is case-sensitive and brittle; use a case-insensitive match to avoid missing variations.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: While case-sensitive matching is brittle, this is a minor, non-critical suggestion in an example. No evidence of varied error messages; improvement is nitpicky with negligible impact.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:64">
two-agent-filter: Prefer mocking the json() method&#39;s return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Stylistic mocking detail with negligible impact; current tests don’t depend on call assertions.</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:64">
single-agent-filter: Prefer mocking the json() method&#39;s return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Stylistic preference with no functional impact here. Assigning a lambda for json() is acceptable and the tests don’t assert call semantics on json(). Too minor to report.</violation>

<violation number="3" location="tests/ci/test_cloud_browser.py:253">
two-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Low-impact test-quality issue; does not affect correctness or cause failures.</violation>

<violation number="4" location="tests/ci/test_cloud_browser.py:253">
single-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Low-impact test design preference. Calling the mock alias directly is not incorrect, and given the function was imported earlier, calling the imported name would bypass the patch anyway. Not a clear, high-impact issue.</violation>

<violation number="5" location="tests/ci/test_cloud_browser.py:294">
two-agent-filter: Assertion message does not match the side_effect; align side_effect to the expected message to avoid a failing test. 

• **Libraries consulted**:</violation>

<violation number="6" location="tests/ci/test_cloud_browser.py:294">
single-agent-filter: Assertion message does not match the side_effect; align side_effect to the expected message to avoid a failing test.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Incorrect assumption: the test calls the previously imported get_cloud_browser_cdp_url, not the patched mock. Therefore the real function’s message (which includes the expected substring) is raised and the test will not fail. The issue reported (message mismatch with side_effect) does not actually occur.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

url = f'{self.api_base_url}/api/v2/browsers'

# Try to get API key from environment variable first, then auth config
api_token = os.getenv('BROWSER_USE_API_KEY')
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

two-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method.

Libraries consulted:

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 64:

<comment>two-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method. 

• **Libraries consulted**: </comment>

<file context>
@@ -0,0 +1,286 @@
+		url = f&#39;{self.api_base_url}/api/v2/browsers&#39;
+
+		# Try to get API key from environment variable first, then auth config
+		api_token = os.getenv(&#39;BROWSER_USE_API_KEY&#39;)
+
+		if not api_token:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Unmapped Agent in getAgentNameFromViolationSource (undefined)

Fix with Cubic

url = f'{self.api_base_url}/api/v2/browsers'

# Try to get API key from environment variable first, then auth config
api_token = os.getenv('BROWSER_USE_API_KEY')
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

single-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method.

Libraries consulted:

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 64:

<comment>single-agent-filter: API token retrieval logic duplicates within CloudBrowserClient:create_browser() and CloudBrowserClient:stop_browser(). Extract into a helper method. 

• **Libraries consulted**: </comment>

<file context>
@@ -0,0 +1,286 @@
+		url = f&#39;{self.api_base_url}/api/v2/browsers&#39;
+
+		# Try to get API key from environment variable first, then auth config
+		api_token = os.getenv(&#39;BROWSER_USE_API_KEY&#39;)
+
+		if not api_token:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Unmapped Agent in getAgentNameFromViolationSource (undefined)

Fix with Cubic

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

two-agent-filter: Grammar/style: use sentence case and add comma after "First".

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Minor grammatical/style issue in README. No functional impact; low importance. Filter out.

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>two-agent-filter: Grammar/style: use sentence case and add comma after &quot;First&quot;.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Minor grammatical/style issue in README. No functional impact; low importance. Filter out.</comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First, set the BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Fix with Cubic

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

single-agent-filter: Grammar/style: use sentence case and add comma after "First".

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.

Libraries consulted:

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>single-agent-filter: Grammar/style: use sentence case and add comma after &quot;First&quot;.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.* 

• **Libraries consulted**: </comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First, set the BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Fix with Cubic

from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
from uuid_extensions import uuid7str

from browser_use.browser.cloud import CloudBrowserAuthError, CloudBrowserError, get_cloud_browser_cdp_url
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

two-agent-filter: The global state management for cloud sessions is architecturally flawed. Using a single global client in cloud.py to manage multiple independent BrowserSession instances from session.py will cause resource leaks. The system can only track the last created browser, so stopping one session will incorrectly terminate another, and earlier sessions will be orphaned.

Libraries consulted:

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 18:

<comment>two-agent-filter: The global state management for cloud sessions is architecturally flawed. Using a single global client in `cloud.py` to manage multiple independent `BrowserSession` instances from `session.py` will cause resource leaks. The system can only track the last created browser, so stopping one session will incorrectly terminate another, and earlier sessions will be orphaned. 

• **Libraries consulted**: </comment>

<file context>
@@ -15,6 +15,8 @@
 from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
 from uuid_extensions import uuid7str
 
+from browser_use.browser.cloud import CloudBrowserAuthError, CloudBrowserError, get_cloud_browser_cdp_url
+
 # CDP logging is now handled by setup_logging() in logging_config.py
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

mock_response = AsyncMock()
mock_response.status_code = 201
mock_response.is_success = True
mock_response.json = lambda: mock_response_data
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

two-agent-filter: Prefer mocking the json() method's return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Stylistic mocking detail with negligible impact; current tests don’t depend on call assertions.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 64:

<comment>two-agent-filter: Prefer mocking the json() method&#39;s return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Stylistic mocking detail with negligible impact; current tests don’t depend on call assertions.</comment>

<file context>
@@ -0,0 +1,333 @@
+			mock_response = AsyncMock()
+			mock_response.status_code = 201
+			mock_response.is_success = True
+			mock_response.json = lambda: mock_response_data
+
+			mock_client = AsyncMock()
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
mock_get_cdp_url.return_value = 'wss://test.proxy.daytona.works'

cdp_url = await mock_get_cdp_url()
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

two-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Low-impact test-quality issue; does not affect correctness or cause failures.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 253:

<comment>two-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Low-impact test-quality issue; does not affect correctness or cause failures.</comment>

<file context>
@@ -0,0 +1,333 @@
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
+			cdp_url = await mock_get_cdp_url()
+			assert cdp_url == &#39;wss://test.proxy.daytona.works&#39;
+			mock_get_cdp_url.assert_called_once()
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

mock_response = AsyncMock()
mock_response.status_code = 201
mock_response.is_success = True
mock_response.json = lambda: mock_response_data
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

single-agent-filter: Prefer mocking the json() method's return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Stylistic preference with no functional impact here. Assigning a lambda for json() is acceptable and the tests don’t assert call semantics on json(). Too minor to report.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 64:

<comment>single-agent-filter: Prefer mocking the json() method&#39;s return_value instead of assigning a lambda to maintain method semantics and enable call assertions.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Stylistic preference with no functional impact here. Assigning a lambda for json() is acceptable and the tests don’t assert call semantics on json(). Too minor to report.</comment>

<file context>
@@ -0,0 +1,333 @@
+			mock_response = AsyncMock()
+			mock_response.status_code = 201
+			mock_response.is_success = True
+			mock_response.json = lambda: mock_response_data
+
+			mock_client = AsyncMock()
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic


# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
mock_cloud_cdp.side_effect = CloudBrowserAuthError('No auth token')
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

single-agent-filter: Assertion message does not match the side_effect; align side_effect to the expected message to avoid a failing test.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Incorrect assumption: the test calls the previously imported get_cloud_browser_cdp_url, not the patched mock. Therefore the real function’s message (which includes the expected substring) is raised and the test will not fail. The issue reported (message mismatch with side_effect) does not actually occur.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 294:

<comment>single-agent-filter: Assertion message does not match the side_effect; align side_effect to the expected message to avoid a failing test.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Incorrect assumption: the test calls the previously imported get_cloud_browser_cdp_url, not the patched mock. Therefore the real function’s message (which includes the expected substring) is raised and the test will not fail. The issue reported (message mismatch with side_effect) does not actually occur.</comment>

<file context>
@@ -0,0 +1,333 @@
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
+		# Verify that the cloud browser client raises the expected error
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
mock_get_cdp_url.return_value = 'wss://test.proxy.daytona.works'

cdp_url = await mock_get_cdp_url()
Copy link

@cubic-staging cubic-staging bot Sep 24, 2025

Choose a reason for hiding this comment

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

single-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Low-impact test design preference. Calling the mock alias directly is not incorrect, and given the function was imported earlier, calling the imported name would bypass the patch anyway. Not a clear, high-impact issue.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 253:

<comment>single-agent-filter: Call the patched function via its original name instead of invoking the mock directly to properly exercise the integration.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Low-impact test design preference. Calling the mock alias directly is not incorrect, and given the function was imported earlier, calling the imported name would bypass the patch anyway. Not a clear, high-impact issue.</comment>

<file context>
@@ -0,0 +1,333 @@
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
+			cdp_url = await mock_get_cdp_url()
+			assert cdp_url == &#39;wss://test.proxy.daytona.works&#39;
+			mock_get_cdp_url.assert_called_once()
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

@sanxroz
Copy link
Collaborator

sanxroz commented Sep 25, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

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

18 issues found across 10 files

Prompt for AI agents (all 18 issues)

Understand the root cause of the following 18 issues and fix them.


<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:513">
Sensitive CDP WebSocket URL exposure: newly assigned cloud CDP URL is later logged/emitted, enabling remote browser hijack if logs are accessed.</violation>

<violation number="2" location="browser_use/browser/session.py:517">
Re-raising CloudBrowserAuthError without chaining drops the original cause. Capture the exception and use &#39;from e&#39; to preserve context.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #1; minor maintainability issue, not functionally impactful.</violation>

<violation number="3" location="browser_use/browser/session.py:521">
Preserve original exception context by chaining the cause when re-raising CloudBrowserError.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Re-raise without exception chaining is a minor debugging concern; no functional impact under medium sensitivity.</violation>

<violation number="4" location="browser_use/browser/session.py:842">
Cloud cleanup does not clear cdp_url, causing subsequent starts to reuse a stale CDP URL instead of provisioning a new cloud session.</violation>
</file>

<file name="browser_use/dom/playground/extraction.py">

<violation number="1" location="browser_use/dom/playground/extraction.py:178">
Use a fallback for tiktoken encoding to avoid runtime errors if &#39;gpt-4.1-mini&#39; is not recognized by the installed tiktoken version (mirror the KeyError fallback used in tests).</violation>
</file>

<file name="examples/browser/cloud_browser.py">

<violation number="1" location="examples/browser/cloud_browser.py:20">
Use spaces instead of tabs for indentation to follow PEP 8 and avoid potential TabError when mixing tabs/spaces.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Tabs vs spaces is a stylistic concern with low functional impact.</violation>

<violation number="2" location="examples/browser/cloud_browser.py:34">
Catch specific CloudBrowserAuthError instead of broad Exception to avoid masking non-auth errors.</violation>

<violation number="3" location="examples/browser/cloud_browser.py:37">
Clarify the auth hint to include the subscription requirement mentioned in the docstring.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Missing subscription mention in hint is a minor documentation issue; low impact.</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:89">
Improve grammar and clarity: add a comma after &quot;First&quot;, format the environment variable as code, and use descriptive link text instead of &quot;here&quot;.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate but purely editorial (grammar, code formatting, link text). No functional or maintainability impact; medium sensitivity—filter low-importance style issues.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:111">
Avoid logging the full session ID at info level. Use a generic message or a redacted/hashed ID.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Session ID not proven sensitive; impact uncertain without policy. Avoid speculative logging restrictions.</violation>

<violation number="2" location="browser_use/browser/cloud.py:112">
Avoid logging full CDP/Live URLs; they may contain sensitive tokens. Log a redacted form or a generic message instead.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: No evidence these URLs contain secrets; tests show generic URLs. Debug-level logging acceptable. Speculative security risk.</violation>

<violation number="3" location="browser_use/browser/cloud.py:124">
Do not wrap asyncio.CancelledError. Add a dedicated `except asyncio.CancelledError: raise` before the broad except to preserve cancellation.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Incorrect: asyncio.CancelledError inherits from BaseException, not Exception, so it won’t be caught by this handler. No bug.</violation>

<violation number="4" location="browser_use/browser/cloud.py:177">
Mixed indentation (spaces vs tabs). Align the comment indentation with surrounding tabs for consistency.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Purely stylistic indentation; no functional impact. Medium sensitivity excludes nitpicks.</violation>

<violation number="5" location="browser_use/browser/cloud.py:212">
Do not wrap asyncio.CancelledError. Add a dedicated `except asyncio.CancelledError: raise` before the broad except to preserve cancellation.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #3: CancelledError won’t be caught by except Exception here. Claim incorrect.</violation>

<violation number="6" location="browser_use/browser/cloud.py:227">
Global client lazy-init is not concurrency-safe; concurrent calls can race. Protect with an asyncio.Lock or initialize eagerly.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: In asyncio, init occurs before any await, so concurrent calls on a single event loop won’t race to create multiple clients. Risk is largely theoretical; insufficient evidence of real impact.</violation>

<violation number="7" location="browser_use/browser/cloud.py:242">
Global _cloud_client races and single-session tracking lead to leaked clients/sessions and wrong stop behavior under concurrency</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:253">
This test calls the mock directly instead of the function under test, providing no real coverage. Replace the mock call with a call to the actual get_cloud_browser_cdp_url().</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:293">
Patching the module function doesn&#39;t affect the already-imported local alias; the patch is ineffective. Patch the name actually used in this module.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

# Use cloud browser service
try:
cloud_cdp_url = await get_cloud_browser_cdp_url()
self.browser_profile.cdp_url = cloud_cdp_url
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Sensitive CDP WebSocket URL exposure: newly assigned cloud CDP URL is later logged/emitted, enabling remote browser hijack if logs are accessed.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 513:

<comment>Sensitive CDP WebSocket URL exposure: newly assigned cloud CDP URL is later logged/emitted, enabling remote browser hijack if logs are accessed.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+					# Use cloud browser service
+					try:
+						cloud_cdp_url = await get_cloud_browser_cdp_url()
+						self.browser_profile.cdp_url = cloud_cdp_url
+						self.browser_profile.is_local = False
+						self.logger.info(&#39;🌤️ Successfully connected to cloud browser service&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic

# pyperclip.copy(text_to_save)

encoding = tiktoken.encoding_for_model('gpt-4o')
encoding = tiktoken.encoding_for_model('gpt-4.1-mini')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Use a fallback for tiktoken encoding to avoid runtime errors if 'gpt-4.1-mini' is not recognized by the installed tiktoken version (mirror the KeyError fallback used in tests).

Prompt for AI agents
Address the following comment on browser_use/dom/playground/extraction.py at line 178:

<comment>Use a fallback for tiktoken encoding to avoid runtime errors if &#39;gpt-4.1-mini&#39; is not recognized by the installed tiktoken version (mirror the KeyError fallback used in tests).</comment>

<file context>
@@ -175,7 +175,7 @@ def get_website_list_for_prompt() -&gt; str:
 				# pyperclip.copy(text_to_save)
 
-				encoding = tiktoken.encoding_for_model(&#39;gpt-4o&#39;)
+				encoding = tiktoken.encoding_for_model(&#39;gpt-4.1-mini&#39;)
 				token_count = len(encoding.encode(text_to_save))
 				print(f&#39;Token count: {token_count}&#39;)
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

except Exception as e:
print(f'❌ Error: {e}')
if 'Authentication' in str(e):
print('💡 Set BROWSER_USE_API_KEY environment variable')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Clarify the auth hint to include the subscription requirement mentioned in the docstring.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Missing subscription mention in hint is a minor documentation issue; low impact.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 37:

<comment>Clarify the auth hint to include the subscription requirement mentioned in the docstring.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Missing subscription mention in hint is a minor documentation issue; low impact.</comment>

<file context>
@@ -0,0 +1,41 @@
+	except Exception as e:
+		print(f&#39;❌ Error: {e}&#39;)
+		if &#39;Authentication&#39; in str(e):
+			print(&#39;💡 Set BROWSER_USE_API_KEY environment variable&#39;)
+
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic



async def main():
"""Basic cloud browser example."""
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Use spaces instead of tabs for indentation to follow PEP 8 and avoid potential TabError when mixing tabs/spaces.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Tabs vs spaces is a stylistic concern with low functional impact.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 20:

<comment>Use spaces instead of tabs for indentation to follow PEP 8 and avoid potential TabError when mixing tabs/spaces.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Tabs vs spaces is a stylistic concern with low functional impact.</comment>

<file context>
@@ -0,0 +1,41 @@
+
+
+async def main():
+	&quot;&quot;&quot;Basic cloud browser example.&quot;&quot;&quot;
+
+	print(&#39;🌤️ Using Browser-Use Cloud Browser&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

try:
result = await agent.run()
print(f'✅ Result: {result}')
except Exception as e:
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Catch specific CloudBrowserAuthError instead of broad Exception to avoid masking non-auth errors.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 34:

<comment>Catch specific CloudBrowserAuthError instead of broad Exception to avoid masking non-auth errors.</comment>

<file context>
@@ -0,0 +1,41 @@
+	try:
+		result = await agent.run()
+		print(f&#39;✅ Result: {result}&#39;)
+	except Exception as e:
+		print(f&#39;❌ Error: {e}&#39;)
+		if &#39;Authentication&#39; in str(e):
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

'Authentication failed. Please make sure you have set the BROWSER_USE_API_KEY environment variable to authenticate with the cloud service.'
)
elif response.status_code == 404:
# Session already stopped or doesn't exist - treating as error and clearing session
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Mixed indentation (spaces vs tabs). Align the comment indentation with surrounding tabs for consistency.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Purely stylistic indentation; no functional impact. Medium sensitivity excludes nitpicks.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 177:

<comment>Mixed indentation (spaces vs tabs). Align the comment indentation with surrounding tabs for consistency.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Purely stylistic indentation; no functional impact. Medium sensitivity excludes nitpicks.</comment>

<file context>
@@ -0,0 +1,286 @@
+					&#39;Authentication failed. Please make sure you have set the BROWSER_USE_API_KEY environment variable to authenticate with the cloud service.&#39;
+				)
+			elif response.status_code == 404:
+                # Session already stopped or doesn&#39;t exist - treating as error and clearing session
+				logger.debug(f&#39;🌤️ Cloud browser session {session_id} not found (already stopped)&#39;)
+				# Clear current session if it was this one
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Suggested change
# Session already stopped or doesn't exist - treating as error and clearing session
# Session already stopped or doesn't exist - treating as error and clearing session
Fix with Cubic

except Exception as e:
if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
raise
raise CloudBrowserError(f'Unexpected error stopping cloud browser: {e}')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Do not wrap asyncio.CancelledError. Add a dedicated except asyncio.CancelledError: raise before the broad except to preserve cancellation.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Same as browser-use#3: CancelledError won’t be caught by except Exception here. Claim incorrect.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 212:

<comment>Do not wrap asyncio.CancelledError. Add a dedicated `except asyncio.CancelledError: raise` before the broad except to preserve cancellation.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #3: CancelledError won’t be caught by except Exception here. Claim incorrect.</comment>

<file context>
@@ -0,0 +1,286 @@
+		except Exception as e:
+			if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
+				raise
+			raise CloudBrowserError(f&#39;Unexpected error stopping cloud browser: {e}&#39;)
+
+	async def close(self):
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

except Exception as e:
if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
raise
raise CloudBrowserError(f'Unexpected error creating cloud browser: {e}')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Do not wrap asyncio.CancelledError. Add a dedicated except asyncio.CancelledError: raise before the broad except to preserve cancellation.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Incorrect: asyncio.CancelledError inherits from BaseException, not Exception, so it won’t be caught by this handler. No bug.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 124:

<comment>Do not wrap asyncio.CancelledError. Add a dedicated `except asyncio.CancelledError: raise` before the broad except to preserve cancellation.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Incorrect: asyncio.CancelledError inherits from BaseException, not Exception, so it won’t be caught by this handler. No bug.</comment>

<file context>
@@ -0,0 +1,286 @@
+		except Exception as e:
+			if isinstance(e, (CloudBrowserError, CloudBrowserAuthError)):
+				raise
+			raise CloudBrowserError(f&#39;Unexpected error creating cloud browser: {e}&#39;)
+
+	async def stop_browser(self, session_id: str | None = None) -&gt; CloudBrowserResponse:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

# Store session ID for cleanup
self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Avoid logging the full session ID at info level. Use a generic message or a redacted/hashed ID.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Session ID not proven sensitive; impact uncertain without policy. Avoid speculative logging restrictions.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 111:

<comment>Avoid logging the full session ID at info level. Use a generic message or a redacted/hashed ID.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Session ID not proven sensitive; impact uncertain without policy. Avoid speculative logging restrictions.</comment>

<file context>
@@ -0,0 +1,286 @@
+			# Store session ID for cleanup
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 25, 2025

Choose a reason for hiding this comment

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

Avoid logging full CDP/Live URLs; they may contain sensitive tokens. Log a redacted form or a generic message instead.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: No evidence these URLs contain secrets; tests show generic URLs. Debug-level logging acceptable. Speculative security risk.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Avoid logging full CDP/Live URLs; they may contain sensitive tokens. Log a redacted form or a generic message instead.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: No evidence these URLs contain secrets; tests show generic URLs. Debug-level logging acceptable. Speculative security risk.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

14 issues found across 10 files

Prompt for AI agents (all 14 issues)

Understand the root cause of the following 14 issues and fix them.


<file name="docs/customize/browser/remote.mdx">

<violation number="1" location="docs/customize/browser/remote.mdx:57">
Insecure remote CDP usage: docs show HTTP cdp_url with no auth; added guidance to use third‑party CDP lacks security notes—risk of unauthorized browser control and MITM.</violation>
</file>

<file name="browser_use/config.py">

<violation number="1" location="browser_use/config.py:290">
Default LLM changed to &#39;gpt-4.1-mini&#39;, but other modules still default to &#39;gpt-4o&#39;, causing tool calls to override the config default unexpectedly. Align defaults or adjust logic to honor config when no model is provided.</violation>

<violation number="2" location="browser_use/config.py:290">
Migration misclassifies valid new-format configs with empty browser_profile and overwrites file (data loss).</violation>
</file>

<file name="README.md">

<violation number="1" location="README.md:31">
Use &quot;daily improvements&quot; instead of &quot;every day improvements&quot; for clarity in user-facing docs.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.*</violation>

<violation number="2" location="README.md:89">
Lowercase &quot;Set&quot; and add article for clarity: &quot;First set the BROWSER_USE_API_KEY environment variable.&quot;</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:112">
Avoid logging sensitive connection URLs (CDP/live). Redact or omit these values to prevent leaking session endpoints.</violation>

<violation number="2" location="browser_use/browser/cloud.py:243">
Race conditions and resource leaks due to unsynchronized global client; non-idempotent 404 handling on stop.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:516">
Re-raising CloudBrowserAuthError without capturing and chaining the original error loses diagnostic details; consider &quot;except CloudBrowserAuthError as e:&quot; and &quot;raise ... from e&quot;.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #1: re-raising CloudBrowserAuthError without chaining loses traceback context but is low impact and largely stylistic. The explicit user-facing message is acceptable; not worth reporting under current sensitivity.</violation>

<violation number="2" location="browser_use/browser/session.py:521">
Re-raising CloudBrowserError without exception chaining loses original traceback/context. Use &quot;from e&quot; to preserve cause.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Technically correct but low severity. Re-raising CloudBrowserError without `from e` loses exception chaining but does not affect functionality or reliability. Given medium sensitivity and focus on impactful issues, this is too minor to report.</violation>

<violation number="3" location="browser_use/browser/session.py:842">
After cleaning up the cloud browser session, the CDP URL is not cleared. Subsequent starts may skip provisioning and try to connect to a stale CDP endpoint, causing connection failures.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:100">
Assertion expects a message not produced by the patched side_effect; align assertion with the side_effect or test the real function.</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:253">
Awaiting a MagicMock from patch leads to TypeError; use AsyncMock via new_callable or await the real function.</violation>
</file>

<file name=".github/ISSUE_TEMPLATE/2_bug_report.yml">

<violation number="1" location=".github/ISSUE_TEMPLATE/2_bug_report.yml:17">
Removing the two trailing spaces removes the intended Markdown line break inside the blockquote, likely causing the following `&lt;a&gt;` image line to render inline. Restore the two spaces to preserve formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The next line begins with a blockquote marker (&gt;) and contains inline HTML. In GitHub/CommonMark, a new blockquote line renders on its own line without needing two trailing spaces. Any change would be cosmetic only and has no functional impact on the issue form. Low importance formatting-only change.

• **Libraries consulted**: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec</violation>

<violation number="2" location=".github/ISSUE_TEMPLATE/2_bug_report.yml:28">
Removing the two trailing spaces removes the intended Markdown line break before the bold warning, likely causing it to render on the same line. Restore the two spaces to preserve formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: This text is inside a YAML literal block scalar (|) where newlines are preserved in the rendered Markdown description. Trailing spaces are unnecessary to force a line break before the bold warning. Even if it rendered inline, the impact is purely cosmetic. Low importance.

• **Libraries consulted**: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

- ✅ Built-in authentication handling
- ✅ Optimized for browser automation

### Third-Party Cloud Browsers
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Insecure remote CDP usage: docs show HTTP cdp_url with no auth; added guidance to use third‑party CDP lacks security notes—risk of unauthorized browser control and MITM.

Prompt for AI agents
Address the following comment on docs/customize/browser/remote.mdx at line 57:

<comment>Insecure remote CDP usage: docs show HTTP cdp_url with no auth; added guidance to use third‑party CDP lacks security notes—risk of unauthorized browser control and MITM.</comment>

<file context>
@@ -23,8 +23,39 @@ agent = Agent(
+- ✅ Built-in authentication handling
+- ✅ Optimized for browser automation
+
+### Third-Party Cloud Browsers
+Get a CDP URL from your favorite browser provider like AnchorBrowser, HyperBrowser, BrowserBase, Steel.dev, etc.
 
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic


# Create default LLM entry
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4o', api_key='your-openai-api-key-here')
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4.1-mini', api_key='your-openai-api-key-here')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Default LLM changed to 'gpt-4.1-mini', but other modules still default to 'gpt-4o', causing tool calls to override the config default unexpectedly. Align defaults or adjust logic to honor config when no model is provided.

Prompt for AI agents
Address the following comment on browser_use/config.py at line 290:

<comment>Default LLM changed to &#39;gpt-4.1-mini&#39;, but other modules still default to &#39;gpt-4o&#39;, causing tool calls to override the config default unexpectedly. Align defaults or adjust logic to honor config when no model is provided.</comment>

<file context>
@@ -287,7 +287,7 @@ def create_default_config() -&gt; DBStyleConfigJSON:
 
 	# Create default LLM entry
-	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4o&#39;, api_key=&#39;your-openai-api-key-here&#39;)
+	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4.1-mini&#39;, api_key=&#39;your-openai-api-key-here&#39;)
 
 	# Create default agent entry
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Lowercase "Set" and add article for clarity: "First set the BROWSER_USE_API_KEY environment variable."

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>Lowercase &quot;Set&quot; and add article for clarity: &quot;First set the BROWSER_USE_API_KEY environment variable.&quot;</comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First set the BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Fix with Cubic

**🚀 Use the latest version!**

> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Use "daily improvements" instead of "every day improvements" for clarity in user-facing docs.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.

Prompt for AI agents
Address the following comment on README.md at line 31:

<comment>Use &quot;daily improvements&quot; instead of &quot;every day improvements&quot; for clarity in user-facing docs.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: objectivity.*</comment>

<file context>
@@ -15,20 +15,20 @@
+**🚀 Use the latest version!**
 
-&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**. 
+&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**.
 &gt; ```bash
 &gt; uv pip install --upgrade browser-use
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship daily improvements for **speed**, **accuracy**, and **UX**.
Fix with Cubic

global _cloud_client

if _cloud_client is None:
_cloud_client = CloudBrowserClient()
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Race conditions and resource leaks due to unsynchronized global client; non-idempotent 404 handling on stop.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 243:

<comment>Race conditions and resource leaks due to unsynchronized global client; non-idempotent 404 handling on stop.</comment>

<file context>
@@ -0,0 +1,286 @@
+	global _cloud_client
+
+	if _cloud_client is None:
+		_cloud_client = CloudBrowserClient()
+
+	try:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
mock_get_cdp_url.return_value = 'wss://test.proxy.daytona.works'

cdp_url = await mock_get_cdp_url()
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Awaiting a MagicMock from patch leads to TypeError; use AsyncMock via new_callable or await the real function.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 253:

<comment>Awaiting a MagicMock from patch leads to TypeError; use AsyncMock via new_callable or await the real function.</comment>

<file context>
@@ -0,0 +1,333 @@
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
+			cdp_url = await mock_get_cdp_url()
+			assert cdp_url == &#39;wss://test.proxy.daytona.works&#39;
+			mock_get_cdp_url.assert_called_once()
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic


# Create default LLM entry
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4o', api_key='your-openai-api-key-here')
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4.1-mini', api_key='your-openai-api-key-here')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Migration misclassifies valid new-format configs with empty browser_profile and overwrites file (data loss).

Prompt for AI agents
Address the following comment on browser_use/config.py at line 290:

<comment>Migration misclassifies valid new-format configs with empty browser_profile and overwrites file (data loss).</comment>

<file context>
@@ -287,7 +287,7 @@ def create_default_config() -&gt; DBStyleConfigJSON:
 
 	# Create default LLM entry
-	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4o&#39;, api_key=&#39;your-openai-api-key-here&#39;)
+	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4.1-mini&#39;, api_key=&#39;your-openai-api-key-here&#39;)
 
 	# Create default agent entry
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

label: Browser Use Version
description: |
What exact version of `browser-use` are you using? (Run `uv pip show browser-use` or `git log -n 1`)
What exact version of `browser-use` are you using? (Run `uv pip show browser-use` or `git log -n 1`)
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Removing the two trailing spaces removes the intended Markdown line break before the bold warning, likely causing it to render on the same line. Restore the two spaces to preserve formatting.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: This text is inside a YAML literal block scalar (|) where newlines are preserved in the rendered Markdown description. Trailing spaces are unnecessary to force a line break before the bold warning. Even if it rendered inline, the impact is purely cosmetic. Low importance.

Libraries consulted: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec

Prompt for AI agents
Address the following comment on .github/ISSUE_TEMPLATE/2_bug_report.yml at line 28:

<comment>Removing the two trailing spaces removes the intended Markdown line break before the bold warning, likely causing it to render on the same line. Restore the two spaces to preserve formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: This text is inside a YAML literal block scalar (|) where newlines are preserved in the rendered Markdown description. Trailing spaces are unnecessary to force a line break before the bold warning. Even if it rendered inline, the impact is purely cosmetic. Low importance.

• **Libraries consulted**: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec</comment>

<file context>
@@ -25,7 +25,7 @@ body:
       label: Browser Use Version
       description: |
-        What exact version of `browser-use` are you using? (Run `uv pip show browser-use` or `git log -n 1`)  
+        What exact version of `browser-use` are you using? (Run `uv pip show browser-use` or `git log -n 1`)
         **DO NOT WRITE `latest release` or `main` or a very old version or we will close your issue!**
       placeholder: &quot;e.g. 0.4.45 or 62760baaefd&quot;
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

> [!IMPORTANT]
> 🙏 Please **go check *right now before filling this out* that you are *actually* on the [⬆️ LATEST VERSION](https://github.com/browser-use/browser-use/releases)**.
> 🚀 We ship changes every hour and we might've already fixed your issue today!
> 🚀 We ship changes every hour and we might've already fixed your issue today!
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Removing the two trailing spaces removes the intended Markdown line break inside the blockquote, likely causing the following <a> image line to render inline. Restore the two spaces to preserve formatting.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: The next line begins with a blockquote marker (>) and contains inline HTML. In GitHub/CommonMark, a new blockquote line renders on its own line without needing two trailing spaces. Any change would be cosmetic only and has no functional impact on the issue form. Low importance formatting-only change.

Libraries consulted: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec

Prompt for AI agents
Address the following comment on .github/ISSUE_TEMPLATE/2_bug_report.yml at line 17:

<comment>Removing the two trailing spaces removes the intended Markdown line break inside the blockquote, likely causing the following `&lt;a&gt;` image line to render inline. Restore the two spaces to preserve formatting.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The next line begins with a blockquote marker (&gt;) and contains inline HTML. In GitHub/CommonMark, a new blockquote line renders on its own line without needing two trailing spaces. Any change would be cosmetic only and has no functional impact on the issue form. Low importance formatting-only change.

• **Libraries consulted**: GitHub Flavored Markdown line breaks, Marked, Markdownguide, CommonMark line breaks, Commonmark-spec</comment>

<file context>
@@ -14,7 +14,7 @@ body:
         &gt; [!IMPORTANT]
         &gt; 🙏 Please **go check *right now before filling this out* that you are *actually* on the [⬆️ LATEST VERSION](https://github.com/browser-use/browser-use/releases)**.
-        &gt; 🚀 We ship changes every hour and we might&#39;ve already fixed your issue today!  
+        &gt; 🚀 We ship changes every hour and we might&#39;ve already fixed your issue today!
         &gt; &lt;a href=&quot;https://github.com/browser-use/browser-use/releases&quot;&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/4cd34ee6-bafb-4f24-87e2-27a31dc5b9a4&quot; width=&quot;500px&quot;/&gt;&lt;/a&gt;
         &gt; If you are running an old version, the **first thing we will ask you to do is *upgrade to the latest version* and try again**:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Avoid logging sensitive connection URLs (CDP/live). Redact or omit these values to prevent leaking session endpoints.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Avoid logging sensitive connection URLs (CDP/live). Redact or omit these values to prevent leaking session endpoints.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

21 issues found across 10 files

Prompt for AI agents (all 21 issues)

Understand the root cause of the following 21 issues and fix them.


<file name="README.md">

<violation number="1" location="README.md:31">
Grammar: &quot;We ship every day improvements&quot; is awkward; use &quot;We ship daily improvements&quot; for clarity.</violation>

<violation number="2" location="README.md:89">
Grammar: Rephrase to &quot;First set the BROWSER_USE_API_KEY environment variable&quot; for clarity and correct casing.</violation>
</file>

<file name="browser_use/browser/profile.py">

<violation number="1" location="browser_use/browser/profile.py:553">
New flag overlaps with existing is_local/cdp_url without validation for mutual exclusivity or precedence, risking ambiguous configuration when multiple are set. Consider adding a model_validator to enforce at most one of these is set and to derive is_local accordingly.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: BrowserSession sets precedence and resolves overlaps: cdp_url (if provided) is used; else cloud_browser=True provisions cloud, sets cdp_url, and forces is_local=False; else is_local=True launches local; otherwise it errors. Configuration is not ambiguous. The absence of a profile-level exclusivity validator is not a bug and has low impact.</violation>
</file>

<file name="docs/customize/browser/remote.mdx">

<violation number="1" location="docs/customize/browser/remote.mdx:32">
Missing comma after ProxySettings(...) before cdp_url causes Python SyntaxError in example.</violation>

<violation number="2" location="docs/customize/browser/remote.mdx:48">
Wrap the environment variable name in backticks for clarity and consistent documentation formatting.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity, documentationImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate observation but purely stylistic. The env var name not in backticks does not affect functionality or clarity, and no style guide in this repo mandates code formatting for env vars. Under medium sensitivity, this lacks impact and should be filtered out.</violation>
</file>

<file name="examples/browser/cloud_browser.py">

<violation number="1" location="examples/browser/cloud_browser.py:34">
Avoid catching broad Exception; catch specific, expected errors or re-raise after handling.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate but low-impact for an example script; it logs the error and exits. Without known specific exception types from external libs, recommending narrower catches risks being incorrect. Not a security/correctness issue.</violation>

<violation number="2" location="examples/browser/cloud_browser.py:36">
String-matching exception messages is brittle; detect auth errors via exception type or structured attributes.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate but minor; provides a helpful hint for common auth misconfig in a demo. No confirmed exception types/codes to check. Not a correctness or security problem.</violation>
</file>

<file name="browser_use/dom/playground/extraction.py">

<violation number="1" location="browser_use/dom/playground/extraction.py:178">
Using tiktoken.encoding_for_model(&#39;gpt-4.1-mini&#39;) without a fallback can raise a KeyError on environments where this model name isn’t mapped, crashing the script. Add try/except with a base encoding fallback (e.g., &#39;o200k_base&#39;) to improve robustness.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Environment-dependent and not a clear, high-confidence bug. Current tiktoken versions likely map &#39;gpt-4.1-mini&#39; given the PR’s migration; without concrete evidence of failure, and since this is a playground script, it’s not important enough to report.

• **Libraries consulted**: tiktoken encoding_for_model, Tiktoken</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:100">
Align the assertion with the mocked side_effect message to avoid false negatives.</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:250">
Patching the function at its source module does not affect the locally imported name; the mock won&#39;t intercept calls made via this module&#39;s imported symbol. Patch the symbol in this module instead.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate but low-impact here: the test calls the mock directly and never uses the imported name, so the patch target mismatch has no effect in this case.</violation>

<violation number="3" location="tests/ci/test_cloud_browser.py:250">
Patch the local import with an AsyncMock so the awaited call is effective and actually tests this module’s reference.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate in theory about patch target/AsyncMock, but in this test the code awaits the patched mock directly and never calls the imported symbol. The real, test-breaking issue is awaiting a non-awaitable MagicMock and not exercising the SUT, which Violation 1 already covers. Reporting both would be redundant; keep the more specific Violation 1.</violation>

<violation number="4" location="tests/ci/test_cloud_browser.py:253">
Call the function under test (which is async) instead of awaiting the mock object; the patch should intercept the local import.</violation>

<violation number="5" location="tests/ci/test_cloud_browser.py:293">
Patch target mismatch: patch the symbol in this module, not the source module, since the function was imported directly. Otherwise the patch is a no-op for calls within this file.</violation>

<violation number="6" location="tests/ci/test_cloud_browser.py:293">
Patch the local import with an AsyncMock to ensure the awaited call uses the mocked side_effect.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:509">
Use the convenience property self.cloud_browser for consistency instead of accessing browser_profile directly.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Same as #1: stylistic suggestion with negligible impact; not worth reporting.</violation>

<violation number="2" location="browser_use/browser/session.py:842">
Cloud browser stop does not clear cdp_url, so subsequent starts may skip provisioning and attempt to reuse a terminated session. Clear cdp_url after cloud cleanup.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:112">
Do not log sensitive connection URLs (CDP). Redact or remove the value to avoid leaking credentials in logs.</violation>

<violation number="2" location="browser_use/browser/cloud.py:113">
Avoid logging the live session URL verbatim. Redact or omit the value to prevent leaking session info.</violation>

<violation number="3" location="browser_use/browser/cloud.py:124">
Preserve exception context by chaining with `from e` when wrapping unexpected errors.</violation>

<violation number="4" location="browser_use/browser/cloud.py:177">
Inconsistent indentation (spaces vs tabs) on this comment. Align with surrounding tab indentation for consistency.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: This is a comment line with spaces used for indentation in a block otherwise using tabs. It has no functional impact in Python and is purely stylistic. Given the sensitivity level and guidance, this is too minor to report.</violation>

<violation number="5" location="browser_use/browser/cloud.py:212">
Use exception chaining (`from e`) to retain the original traceback when wrapping errors.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

**🚀 Use the latest version!**

> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Grammar: "We ship every day improvements" is awkward; use "We ship daily improvements" for clarity.

Prompt for AI agents
Address the following comment on README.md at line 31:

<comment>Grammar: &quot;We ship every day improvements&quot; is awkward; use &quot;We ship daily improvements&quot; for clarity.</comment>

<file context>
@@ -15,20 +15,20 @@
+**🚀 Use the latest version!**
 
-&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**. 
+&gt; We ship every day improvements for **speed**, **accuracy**, and **UX**.
 &gt; ```bash
 &gt; uv pip install --upgrade browser-use
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Suggested change
> We ship every day improvements for **speed**, **accuracy**, and **UX**.
> We ship daily improvements for **speed**, **accuracy**, and **UX**.
Fix with Cubic

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Grammar: Rephrase to "First set the BROWSER_USE_API_KEY environment variable" for clarity and correct casing.

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>Grammar: Rephrase to &quot;First set the BROWSER_USE_API_KEY environment variable&quot; for clarity and correct casing.</comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First set the BROWSER_USE_API_KEY environment variable. You can get your API key [here](https://cloud.browser-use.com).
Fix with Cubic

# Session/connection configuration
cdp_url: str | None = Field(default=None, description='CDP URL for connecting to existing browser instance')
is_local: bool = Field(default=False, description='Whether this is a local browser instance')
cloud_browser: bool = Field(default=False, description='Use browser-use cloud browser service instead of local browser')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

New flag overlaps with existing is_local/cdp_url without validation for mutual exclusivity or precedence, risking ambiguous configuration when multiple are set. Consider adding a model_validator to enforce at most one of these is set and to derive is_local accordingly.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: BrowserSession sets precedence and resolves overlaps: cdp_url (if provided) is used; else cloud_browser=True provisions cloud, sets cdp_url, and forces is_local=False; else is_local=True launches local; otherwise it errors. Configuration is not ambiguous. The absence of a profile-level exclusivity validator is not a bug and has low impact.

Prompt for AI agents
Address the following comment on browser_use/browser/profile.py at line 553:

<comment>New flag overlaps with existing is_local/cdp_url without validation for mutual exclusivity or precedence, risking ambiguous configuration when multiple are set. Consider adding a model_validator to enforce at most one of these is set and to derive is_local accordingly.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: BrowserSession sets precedence and resolves overlaps: cdp_url (if provided) is used; else cloud_browser=True provisions cloud, sets cdp_url, and forces is_local=False; else is_local=True launches local; otherwise it errors. Configuration is not ambiguous. The absence of a profile-level exclusivity validator is not a bug and has low impact.</comment>

<file context>
@@ -550,6 +550,7 @@ class BrowserProfile(BrowserConnectArgs, BrowserLaunchPersistentContextArgs, Bro
 	# Session/connection configuration
 	cdp_url: str | None = Field(default=None, description=&#39;CDP URL for connecting to existing browser instance&#39;)
 	is_local: bool = Field(default=False, description=&#39;Whether this is a local browser instance&#39;)
+	cloud_browser: bool = Field(default=False, description=&#39;Use browser-use cloud browser service instead of local browser&#39;)
 	# label: str = &#39;default&#39;
 
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic


**Prerequisites:**
1. Get an API key from [cloud.browser-use.com](https://cloud.browser-use.com)
2. Set BROWSER_USE_API_KEY environment variable
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Wrap the environment variable name in backticks for clarity and consistent documentation formatting.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity, documentationImpact.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Accurate observation but purely stylistic. The env var name not in backticks does not affect functionality or clarity, and no style guide in this repo mandates code formatting for env vars. Under medium sensitivity, this lacks impact and should be filtered out.

Prompt for AI agents
Address the following comment on docs/customize/browser/remote.mdx at line 48:

<comment>Wrap the environment variable name in backticks for clarity and consistent documentation formatting.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: commentPurpose, functionalImpact, objectivity, documentationImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate observation but purely stylistic. The env var name not in backticks does not affect functionality or clarity, and no style guide in this repo mandates code formatting for env vars. Under medium sensitivity, this lacks impact and should be filtered out.</comment>

<file context>
@@ -23,8 +23,39 @@ agent = Agent(
+
+**Prerequisites:**
+1. Get an API key from [cloud.browser-use.com](https://cloud.browser-use.com)
+2. Set BROWSER_USE_API_KEY environment variable
+
+**Benefits:**
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
2. Set BROWSER_USE_API_KEY environment variable
2. Set `BROWSER_USE_API_KEY` environment variable
Fix with Cubic

print(f'✅ Result: {result}')
except Exception as e:
print(f'❌ Error: {e}')
if 'Authentication' in str(e):
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

String-matching exception messages is brittle; detect auth errors via exception type or structured attributes.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Accurate but minor; provides a helpful hint for common auth misconfig in a demo. No confirmed exception types/codes to check. Not a correctness or security problem.

Prompt for AI agents
Address the following comment on examples/browser/cloud_browser.py at line 36:

<comment>String-matching exception messages is brittle; detect auth errors via exception type or structured attributes.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate but minor; provides a helpful hint for common auth misconfig in a demo. No confirmed exception types/codes to check. Not a correctness or security problem.</comment>

<file context>
@@ -0,0 +1,41 @@
+		print(f&#39;✅ Result: {result}&#39;)
+	except Exception as e:
+		print(f&#39;❌ Error: {e}&#39;)
+		if &#39;Authentication&#39; in str(e):
+			print(&#39;💡 Set BROWSER_USE_API_KEY environment variable&#39;)
+
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Do not log sensitive connection URLs (CDP). Redact or remove the value to avoid leaking credentials in logs.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Do not log sensitive connection URLs (CDP). Redact or remove the value to avoid leaking credentials in logs.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

profile = BrowserProfile(cloud_browser=True)

# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Patch the local import with an AsyncMock to ensure the awaited call uses the mocked side_effect.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 293:

<comment>Patch the local import with an AsyncMock to ensure the awaited call uses the mocked side_effect.</comment>

<file context>
@@ -0,0 +1,333 @@
+	profile = BrowserProfile(cloud_browser=True)
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with pytest.raises(CloudBrowserAuthError) as exc_info:
await client.create_browser()

assert 'BROWSER_USE_API_KEY environment variable' in str(exc_info.value)
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Align the assertion with the mocked side_effect message to avoid false negatives.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 100:

<comment>Align the assertion with the mocked side_effect message to avoid false negatives.</comment>

<file context>
@@ -0,0 +1,333 @@
+			with pytest.raises(CloudBrowserAuthError) as exc_info:
+				await client.create_browser()
+
+			assert &#39;BROWSER_USE_API_KEY environment variable&#39; in str(exc_info.value)
+
+	async def test_create_browser_http_401(self, mock_auth_config):
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
mock_get_cdp_url.return_value = 'wss://test.proxy.daytona.works'

cdp_url = await mock_get_cdp_url()
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Call the function under test (which is async) instead of awaiting the mock object; the patch should intercept the local import.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 253:

<comment>Call the function under test (which is async) instead of awaiting the mock object; the patch should intercept the local import.</comment>

<file context>
@@ -0,0 +1,333 @@
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
+			cdp_url = await mock_get_cdp_url()
+			assert cdp_url == &#39;wss://test.proxy.daytona.works&#39;
+			mock_get_cdp_url.assert_called_once()
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

assert session.cloud_browser is True

# Test that get_cloud_browser_cdp_url works with mocked API
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Patch the local import with an AsyncMock so the awaited call is effective and actually tests this module’s reference.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Accurate in theory about patch target/AsyncMock, but in this test the code awaits the patched mock directly and never calls the imported symbol. The real, test-breaking issue is awaiting a non-awaitable MagicMock and not exercising the SUT, which Violation 1 already covers. Reporting both would be redundant; keep the more specific Violation 1.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 250:

<comment>Patch the local import with an AsyncMock so the awaited call is effective and actually tests this module’s reference.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Accurate in theory about patch target/AsyncMock, but in this test the code awaits the patched mock directly and never calls the imported symbol. The real, test-breaking issue is awaiting a non-awaitable MagicMock and not exercising the SUT, which Violation 1 already covers. Reporting both would be redundant; keep the more specific Violation 1.</comment>

<file context>
@@ -0,0 +1,333 @@
+		assert session.cloud_browser is True
+
+		# Test that get_cloud_browser_cdp_url works with mocked API
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

7 issues found across 10 files

Prompt for AI agents (all 7 issues)

Understand the root cause of the following 7 issues and fix them.


<file name="README.md">

<violation number="1" location="README.md:89">
Grammar and formatting: add comma after &quot;First&quot; and wrap the environment variable in backticks for consistency and clarity.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Purely stylistic/grammar inconsistency in README (“First Set…”, missing comma, no backticks). No functional, security, or maintainability impact. Medium sensitivity dictates filtering such low-impact issues.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:227">
The use of a global `_cloud_client` creates shared state between `BrowserSession` instances, making concurrent cloud browser sessions unsafe. This leads to race conditions where stopping one session can terminate another and cause resource leaks.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:64">
Use a regular Mock for httpx.Response and set json.return_value instead of a lambda on an AsyncMock to better match httpx.Response behavior.


        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Using AsyncMock for the response and assigning a sync lambda to `json` matches httpx.Response.json() being synchronous and does not break functionality here. This is a stylistic realism improvement, not a clear bug.</violation>

<violation number="2" location="tests/ci/test_cloud_browser.py:293">
Patching `browser_use.browser.cloud.get_cloud_browser_cdp_url` does not affect the already imported local `get_cloud_browser_cdp_url`; the test calls the real function instead of the mock. Patch the local symbol or call via the module attribute.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:517">
Re-wrapping CloudBrowserAuthError obscures the original error context; prefer re-raising the caught exception to retain traceback.</violation>

<violation number="2" location="browser_use/browser/session.py:521">
Re-wrapping CloudBrowserError loses original traceback; re-raise the original exception to preserve context.</violation>

<violation number="3" location="browser_use/browser/session.py:840">
Avoid in-function import; move cleanup_cloud_client import to module level for consistency and to prevent repeated imports.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: In-function import of cleanup_cloud_client is a minor style preference with negligible impact; Python caches imports, and this may avoid loading cloud code unless used. Not important enough to report.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

)
```

First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Grammar and formatting: add comma after "First" and wrap the environment variable in backticks for consistency and clarity.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Purely stylistic/grammar inconsistency in README (“First Set…”, missing comma, no backticks). No functional, security, or maintainability impact. Medium sensitivity dictates filtering such low-impact issues.

Prompt for AI agents
Address the following comment on README.md at line 89:

<comment>Grammar and formatting: add comma after &quot;First&quot; and wrap the environment variable in backticks for consistency and clarity.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Purely stylistic/grammar inconsistency in README (“First Set…”, missing comma, no backticks). No functional, security, or maintainability impact. Medium sensitivity dictates filtering such low-impact issues.</comment>

<file context>
@@ -74,6 +74,22 @@ OPENAI_API_KEY=
+)
+```
+
+First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
+
+For other settings, models, and more, check out the [Cloud documentation 📕](https://docs.cloud.browser-use.com).
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
First Set BROWSER_USE_API_KEY environment variable. You can get your API key from [here](https://cloud.browser-use.com).
First, set the `BROWSER_USE_API_KEY` environment variable. You can get your API key from [here](https://cloud.browser-use.com).
Fix with Cubic



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The use of a global _cloud_client creates shared state between BrowserSession instances, making concurrent cloud browser sessions unsafe. This leads to race conditions where stopping one session can terminate another and cause resource leaks.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>The use of a global `_cloud_client` creates shared state between `BrowserSession` instances, making concurrent cloud browser sessions unsafe. This leads to race conditions where stopping one session can terminate another and cause resource leaks.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

mock_response = AsyncMock()
mock_response.status_code = 201
mock_response.is_success = True
mock_response.json = lambda: mock_response_data
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Use a regular Mock for httpx.Response and set json.return_value instead of a lambda on an AsyncMock to better match httpx.Response behavior.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Using AsyncMock for the response and assigning a sync lambda to json matches httpx.Response.json() being synchronous and does not break functionality here. This is a stylistic realism improvement, not a clear bug.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 64:

<comment>Use a regular Mock for httpx.Response and set json.return_value instead of a lambda on an AsyncMock to better match httpx.Response behavior.


        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Using AsyncMock for the response and assigning a sync lambda to `json` matches httpx.Response.json() being synchronous and does not break functionality here. This is a stylistic realism improvement, not a clear bug.</comment>

<file context>
@@ -0,0 +1,333 @@
+			mock_response = AsyncMock()
+			mock_response.status_code = 201
+			mock_response.is_success = True
+			mock_response.json = lambda: mock_response_data
+
+			mock_client = AsyncMock()
</file context>

[internal] Confidence score: 6/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

profile = BrowserProfile(cloud_browser=True)

# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Patching browser_use.browser.cloud.get_cloud_browser_cdp_url does not affect the already imported local get_cloud_browser_cdp_url; the test calls the real function instead of the mock. Patch the local symbol or call via the module attribute.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 293:

<comment>Patching `browser_use.browser.cloud.get_cloud_browser_cdp_url` does not affect the already imported local `get_cloud_browser_cdp_url`; the test calls the real function instead of the mock. Patch the local symbol or call via the module attribute.
</comment>

<file context>
@@ -0,0 +1,333 @@
+	profile = BrowserProfile(cloud_browser=True)
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

# Clean up cloud browser session if using cloud browser
if self.browser_profile.cloud_browser:
try:
from browser_use.browser.cloud import cleanup_cloud_client
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Avoid in-function import; move cleanup_cloud_client import to module level for consistency and to prevent repeated imports.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: In-function import of cleanup_cloud_client is a minor style preference with negligible impact; Python caches imports, and this may avoid loading cloud code unless used. Not important enough to report.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 840:

<comment>Avoid in-function import; move cleanup_cloud_client import to module level for consistency and to prevent repeated imports.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: functionalImpact, objectivity.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: In-function import of cleanup_cloud_client is a minor style preference with negligible impact; Python caches imports, and this may avoid loading cloud code unless used. Not important enough to report.</comment>

<file context>
@@ -813,6 +834,16 @@ async def on_BrowserStopEvent(self, event: BrowserStopEvent) -&gt; None:
+			# Clean up cloud browser session if using cloud browser
+			if self.browser_profile.cloud_browser:
+				try:
+					from browser_use.browser.cloud import cleanup_cloud_client
+
+					await cleanup_cloud_client()
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

self.browser_profile.is_local = False
self.logger.info('🌤️ Successfully connected to cloud browser service')
except CloudBrowserAuthError:
raise CloudBrowserAuthError(
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Re-wrapping CloudBrowserAuthError obscures the original error context; prefer re-raising the caught exception to retain traceback.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 517:

<comment>Re-wrapping CloudBrowserAuthError obscures the original error context; prefer re-raising the caught exception to retain traceback.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+						self.browser_profile.is_local = False
+						self.logger.info(&#39;🌤️ Successfully connected to cloud browser service&#39;)
+					except CloudBrowserAuthError:
+						raise CloudBrowserAuthError(
+							&#39;Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable&#39;
+						)
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

'Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable'
)
except CloudBrowserError as e:
raise CloudBrowserError(f'Failed to create cloud browser: {e}')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Re-wrapping CloudBrowserError loses original traceback; re-raise the original exception to preserve context.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 521:

<comment>Re-wrapping CloudBrowserError loses original traceback; re-raise the original exception to preserve context.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+							&#39;Authentication failed for cloud browser service. Set BROWSER_USE_API_KEY environment variable&#39;
+						)
+					except CloudBrowserError as e:
+						raise CloudBrowserError(f&#39;Failed to create cloud browser: {e}&#39;)
+				elif self.is_local:
 					# Launch local browser using event-driven approach
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

5 issues found across 10 files

Prompt for AI agents (all 5 issues)

Understand the root cause of the following 5 issues and fix them.


<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:112">
Sensitive data exposure: Logging CDP and Live URLs can leak session tokens/endpoints enabling session hijack.</violation>

<violation number="2" location="browser_use/browser/cloud.py:227">
The use of a global stateful client (`_cloud_client`) for managing cloud browser sessions creates a race condition. When multiple cloud browsers are used, stopping one session will incorrectly terminate another, leading to orphaned resources and unpredictable behavior.</violation>
</file>

<file name="browser_use/browser/profile.py">

<violation number="1" location="browser_use/browser/profile.py:553">
The system does not differentiate between browser launch and connect arguments in `BrowserProfile`. When `cloud_browser=True`, incompatible launch arguments (e.g., `headless`, `proxy`) are passed to the connection logic, which will cause a crash.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Factually incorrect. Cloud connection uses Session.connect() with an internal CDPClient and only applies BrowserProfile.headers for the /json/version request. No Playwright connect() is called and launch-only args (headless, proxy, args) are not passed to the connect path. Local launch via LocalBrowserWatchdog (subprocess) is separate.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:294">
The mocked cloud CDP helper raises `CloudBrowserAuthError(&#39;No auth token&#39;)`, but the test later asserts the exception message contains `BROWSER_USE_API_KEY environment variable`, so this test will always fail. Update the mock to raise the same message you&#39;re asserting against so the expectation matches the simulated error.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The test imports get_cloud_browser_cdp_url directly, then patches browser_use.browser.cloud.get_cloud_browser_cdp_url. Calling the imported name invokes the real function, not the mock. The real create_browser raises CloudBrowserAuthError with a message containing &#39;BROWSER_USE_API_KEY environment variable&#39; when no token is present, so the assertion matches and the test will pass. This is at most a minor mock-target nit and not a valid bug.</violation>
</file>

<file name="browser_use/dom/playground/extraction.py">

<violation number="1" location="browser_use/dom/playground/extraction.py:178">
Unknown model &#39;gpt-4.1-mini&#39; may raise at runtime, causing repeated loop failures and blocking interaction.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Speculative and low impact. The repo standardizes on &#39;gpt-4.1-mini&#39;. tiktoken.encoding_for_model generally falls back to a compatible encoding for unknown GPT-4-family names with a warning rather than raising. This is in a playground script, not core runtime; insufficient evidence of a definite runtime failure.

• **Libraries consulted**: openai tiktoken encoding_for_model, Tiktoken</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The use of a global stateful client (_cloud_client) for managing cloud browser sessions creates a race condition. When multiple cloud browsers are used, stopping one session will incorrectly terminate another, leading to orphaned resources and unpredictable behavior.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>The use of a global stateful client (`_cloud_client`) for managing cloud browser sessions creates a race condition. When multiple cloud browsers are used, stopping one session will incorrectly terminate another, leading to orphaned resources and unpredictable behavior.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

# Session/connection configuration
cdp_url: str | None = Field(default=None, description='CDP URL for connecting to existing browser instance')
is_local: bool = Field(default=False, description='Whether this is a local browser instance')
cloud_browser: bool = Field(default=False, description='Use browser-use cloud browser service instead of local browser')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The system does not differentiate between browser launch and connect arguments in BrowserProfile. When cloud_browser=True, incompatible launch arguments (e.g., headless, proxy) are passed to the connection logic, which will cause a crash.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Factually incorrect. Cloud connection uses Session.connect() with an internal CDPClient and only applies BrowserProfile.headers for the /json/version request. No Playwright connect() is called and launch-only args (headless, proxy, args) are not passed to the connect path. Local launch via LocalBrowserWatchdog (subprocess) is separate.

Prompt for AI agents
Address the following comment on browser_use/browser/profile.py at line 553:

<comment>The system does not differentiate between browser launch and connect arguments in `BrowserProfile`. When `cloud_browser=True`, incompatible launch arguments (e.g., `headless`, `proxy`) are passed to the connection logic, which will cause a crash.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Factually incorrect. Cloud connection uses Session.connect() with an internal CDPClient and only applies BrowserProfile.headers for the /json/version request. No Playwright connect() is called and launch-only args (headless, proxy, args) are not passed to the connect path. Local launch via LocalBrowserWatchdog (subprocess) is separate.</comment>

<file context>
@@ -550,6 +550,7 @@ class BrowserProfile(BrowserConnectArgs, BrowserLaunchPersistentContextArgs, Bro
 	# Session/connection configuration
 	cdp_url: str | None = Field(default=None, description=&#39;CDP URL for connecting to existing browser instance&#39;)
 	is_local: bool = Field(default=False, description=&#39;Whether this is a local browser instance&#39;)
+	cloud_browser: bool = Field(default=False, description=&#39;Use browser-use cloud browser service instead of local browser&#39;)
 	# label: str = &#39;default&#39;
 
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: System Design Agent

Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Sensitive data exposure: Logging CDP and Live URLs can leak session tokens/endpoints enabling session hijack.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Sensitive data exposure: Logging CDP and Live URLs can leak session tokens/endpoints enabling session hijack.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic


# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
mock_cloud_cdp.side_effect = CloudBrowserAuthError('No auth token')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The mocked cloud CDP helper raises CloudBrowserAuthError('No auth token'), but the test later asserts the exception message contains BROWSER_USE_API_KEY environment variable, so this test will always fail. Update the mock to raise the same message you're asserting against so the expectation matches the simulated error.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: The test imports get_cloud_browser_cdp_url directly, then patches browser_use.browser.cloud.get_cloud_browser_cdp_url. Calling the imported name invokes the real function, not the mock. The real create_browser raises CloudBrowserAuthError with a message containing 'BROWSER_USE_API_KEY environment variable' when no token is present, so the assertion matches and the test will pass. This is at most a minor mock-target nit and not a valid bug.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 294:

<comment>The mocked cloud CDP helper raises `CloudBrowserAuthError(&#39;No auth token&#39;)`, but the test later asserts the exception message contains `BROWSER_USE_API_KEY environment variable`, so this test will always fail. Update the mock to raise the same message you&#39;re asserting against so the expectation matches the simulated error.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The test imports get_cloud_browser_cdp_url directly, then patches browser_use.browser.cloud.get_cloud_browser_cdp_url. Calling the imported name invokes the real function, not the mock. The real create_browser raises CloudBrowserAuthError with a message containing &#39;BROWSER_USE_API_KEY environment variable&#39; when no token is present, so the assertion matches and the test will pass. This is at most a minor mock-target nit and not a valid bug.</comment>

<file context>
@@ -0,0 +1,333 @@
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
+		# Verify that the cloud browser client raises the expected error
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

# pyperclip.copy(text_to_save)

encoding = tiktoken.encoding_for_model('gpt-4o')
encoding = tiktoken.encoding_for_model('gpt-4.1-mini')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Unknown model 'gpt-4.1-mini' may raise at runtime, causing repeated loop failures and blocking interaction.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Speculative and low impact. The repo standardizes on 'gpt-4.1-mini'. tiktoken.encoding_for_model generally falls back to a compatible encoding for unknown GPT-4-family names with a warning rather than raising. This is in a playground script, not core runtime; insufficient evidence of a definite runtime failure.

Libraries consulted: openai tiktoken encoding_for_model, Tiktoken

Prompt for AI agents
Address the following comment on browser_use/dom/playground/extraction.py at line 178:

<comment>Unknown model &#39;gpt-4.1-mini&#39; may raise at runtime, causing repeated loop failures and blocking interaction.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Speculative and low impact. The repo standardizes on &#39;gpt-4.1-mini&#39;. tiktoken.encoding_for_model generally falls back to a compatible encoding for unknown GPT-4-family names with a warning rather than raising. This is in a playground script, not core runtime; insufficient evidence of a definite runtime failure.

• **Libraries consulted**: openai tiktoken encoding_for_model, Tiktoken</comment>

<file context>
@@ -175,7 +175,7 @@ def get_website_list_for_prompt() -&gt; str:
 				# pyperclip.copy(text_to_save)
 
-				encoding = tiktoken.encoding_for_model(&#39;gpt-4o&#39;)
+				encoding = tiktoken.encoding_for_model(&#39;gpt-4.1-mini&#39;)
 				token_count = len(encoding.encode(text_to_save))
 				print(f&#39;Token count: {token_count}&#39;)
</file context>

[internal] Confidence score: 7/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 10 files

Prompt for AI agents (all 3 issues)

Understand the root cause of the following 3 issues and fix them.


<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:227">
The use of a global client (`_cloud_client`) with session-specific state (`current_session_id`) creates a race condition. Concurrent browser sessions will overwrite each other&#39;s session IDs on this shared client, leading to resource leaks and incorrect session termination when `BrowserSession` is stopped.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:842">
Once the cloud browser session is cleaned up you need to clear `browser_profile.cdp_url`; otherwise `reset()` leaves the stale CDP URL (because `is_local` was set to False when provisioning), so the next `BrowserStartEvent` skips provisioning and fails when it tries to reconnect to the torn-down session. Please reset the profile URL (and related flags) after `cleanup_cloud_client()`.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:100">
The mocked `CloudBrowserAuthError` raises with message &#39;No auth token&#39;, so asserting for &#39;BROWSER_USE_API_KEY environment variable&#39; will fail every run. Update the expected message (or mock) to match the actual error.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: False positive: the test calls the locally imported get_cloud_browser_cdp_url, so the patch does not apply. The real function raises CloudBrowserAuthError with a message that includes &#39;BROWSER_USE_API_KEY environment variable&#39;, matching the assertion.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The use of a global client (_cloud_client) with session-specific state (current_session_id) creates a race condition. Concurrent browser sessions will overwrite each other's session IDs on this shared client, leading to resource leaks and incorrect session termination when BrowserSession is stopped.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>The use of a global client (`_cloud_client`) with session-specific state (`current_session_id`) creates a race condition. Concurrent browser sessions will overwrite each other&#39;s session IDs on this shared client, leading to resource leaks and incorrect session termination when `BrowserSession` is stopped.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

try:
from browser_use.browser.cloud import cleanup_cloud_client

await cleanup_cloud_client()
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Once the cloud browser session is cleaned up you need to clear browser_profile.cdp_url; otherwise reset() leaves the stale CDP URL (because is_local was set to False when provisioning), so the next BrowserStartEvent skips provisioning and fails when it tries to reconnect to the torn-down session. Please reset the profile URL (and related flags) after cleanup_cloud_client().

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 842:

<comment>Once the cloud browser session is cleaned up you need to clear `browser_profile.cdp_url`; otherwise `reset()` leaves the stale CDP URL (because `is_local` was set to False when provisioning), so the next `BrowserStartEvent` skips provisioning and fails when it tries to reconnect to the torn-down session. Please reset the profile URL (and related flags) after `cleanup_cloud_client()`.</comment>

<file context>
@@ -813,6 +834,16 @@ async def on_BrowserStopEvent(self, event: BrowserStopEvent) -&gt; None:
+				try:
+					from browser_use.browser.cloud import cleanup_cloud_client
+
+					await cleanup_cloud_client()
+					self.logger.info(&#39;🌤️ Cloud browser session cleaned up&#39;)
+				except Exception as e:
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with pytest.raises(CloudBrowserAuthError) as exc_info:
await client.create_browser()

assert 'BROWSER_USE_API_KEY environment variable' in str(exc_info.value)
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

The mocked CloudBrowserAuthError raises with message 'No auth token', so asserting for 'BROWSER_USE_API_KEY environment variable' will fail every run. Update the expected message (or mock) to match the actual error.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: False positive: the test calls the locally imported get_cloud_browser_cdp_url, so the patch does not apply. The real function raises CloudBrowserAuthError with a message that includes 'BROWSER_USE_API_KEY environment variable', matching the assertion.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 100:

<comment>The mocked `CloudBrowserAuthError` raises with message &#39;No auth token&#39;, so asserting for &#39;BROWSER_USE_API_KEY environment variable&#39; will fail every run. Update the expected message (or mock) to match the actual error.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: False positive: the test calls the locally imported get_cloud_browser_cdp_url, so the patch does not apply. The real function raises CloudBrowserAuthError with a message that includes &#39;BROWSER_USE_API_KEY environment variable&#39;, matching the assertion.</comment>

<file context>
@@ -0,0 +1,333 @@
+			with pytest.raises(CloudBrowserAuthError) as exc_info:
+				await client.create_browser()
+
+			assert &#39;BROWSER_USE_API_KEY environment variable&#39; in str(exc_info.value)
+
+	async def test_create_browser_http_401(self, mock_auth_config):
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 10 files

Prompt for AI agents (all 3 issues)

Understand the root cause of the following 3 issues and fix them.


<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:842">
Stopping a cloud browser session removes the remote instance but leaves `browser_profile.cdp_url` pointing at the terminated CDP endpoint. Because the start branch marks the profile as non-local, `reset()` never clears that field afterward, so the next `start()` attempt on this session reuses a dead WebSocket and fails. Please clear or replace the CDP URL when cleaning up cloud sessions so subsequent restarts can obtain a fresh connection.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:227">
Global singleton _cloud_client is not concurrency-safe and couples all sessions, causing cross-session interference and orphaned/incorrectly stopped sessions.</violation>
</file>

<file name="browser_use/config.py">

<violation number="1" location="browser_use/config.py:290">
Valid DB-style config with empty or partially valid browser_profile is erroneously overwritten, causing data loss.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

try:
from browser_use.browser.cloud import cleanup_cloud_client

await cleanup_cloud_client()
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Stopping a cloud browser session removes the remote instance but leaves browser_profile.cdp_url pointing at the terminated CDP endpoint. Because the start branch marks the profile as non-local, reset() never clears that field afterward, so the next start() attempt on this session reuses a dead WebSocket and fails. Please clear or replace the CDP URL when cleaning up cloud sessions so subsequent restarts can obtain a fresh connection.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 842:

<comment>Stopping a cloud browser session removes the remote instance but leaves `browser_profile.cdp_url` pointing at the terminated CDP endpoint. Because the start branch marks the profile as non-local, `reset()` never clears that field afterward, so the next `start()` attempt on this session reuses a dead WebSocket and fails. Please clear or replace the CDP URL when cleaning up cloud sessions so subsequent restarts can obtain a fresh connection.</comment>

<file context>
@@ -813,6 +834,16 @@ async def on_BrowserStopEvent(self, event: BrowserStopEvent) -&gt; None:
+				try:
+					from browser_use.browser.cloud import cleanup_cloud_client
+
+					await cleanup_cloud_client()
+					self.logger.info(&#39;🌤️ Cloud browser session cleaned up&#39;)
+				except Exception as e:
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Global singleton _cloud_client is not concurrency-safe and couples all sessions, causing cross-session interference and orphaned/incorrectly stopped sessions.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>Global singleton _cloud_client is not concurrency-safe and couples all sessions, causing cross-session interference and orphaned/incorrectly stopped sessions.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic


# Create default LLM entry
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4o', api_key='your-openai-api-key-here')
new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model='gpt-4.1-mini', api_key='your-openai-api-key-here')
Copy link

@cubic-staging cubic-staging bot Sep 26, 2025

Choose a reason for hiding this comment

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

Valid DB-style config with empty or partially valid browser_profile is erroneously overwritten, causing data loss.

Prompt for AI agents
Address the following comment on browser_use/config.py at line 290:

<comment>Valid DB-style config with empty or partially valid browser_profile is erroneously overwritten, causing data loss.</comment>

<file context>
@@ -287,7 +287,7 @@ def create_default_config() -&gt; DBStyleConfigJSON:
 
 	# Create default LLM entry
-	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4o&#39;, api_key=&#39;your-openai-api-key-here&#39;)
+	new_config.llm[llm_id] = LLMEntry(id=llm_id, default=True, model=&#39;gpt-4.1-mini&#39;, api_key=&#39;your-openai-api-key-here&#39;)
 
 	# Create default agent entry
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

No issues found across 10 files

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 10 files

Prompt for AI agents (all 3 issues)

Understand the root cause of the following 3 issues and fix them.


<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:109">
CloudBrowserClient tracks only a single session id, so concurrent get/stop calls stop the wrong session and leak the first browser instance.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:842">
After cleaning up the cloud browser you leave `browser_profile.cdp_url` pointing at the terminated session, so the next start skips provisioning and tries to reconnect to a dead CDP endpoint. Please clear the CDP URL when shutting down cloud sessions to avoid this functional breakage.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: No reasoning provided</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:253">
This test never exercises `get_cloud_browser_cdp_url`—it calls the mock directly, so the helper could break without the test failing. Call the real function (which is patched) instead of invoking the mock to ensure coverage.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

browser_response = CloudBrowserResponse(**browser_data)

# Store session ID for cleanup
self.current_session_id = browser_response.id
Copy link

@cubic-staging cubic-staging bot Oct 6, 2025

Choose a reason for hiding this comment

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

CloudBrowserClient tracks only a single session id, so concurrent get/stop calls stop the wrong session and leak the first browser instance.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 109:

<comment>CloudBrowserClient tracks only a single session id, so concurrent get/stop calls stop the wrong session and leak the first browser instance.</comment>

<file context>
@@ -0,0 +1,286 @@
+			browser_response = CloudBrowserResponse(**browser_data)
+
+			# Store session ID for cleanup
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

try:
from browser_use.browser.cloud import cleanup_cloud_client

await cleanup_cloud_client()
Copy link

@cubic-staging cubic-staging bot Oct 6, 2025

Choose a reason for hiding this comment

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

After cleaning up the cloud browser you leave browser_profile.cdp_url pointing at the terminated session, so the next start skips provisioning and tries to reconnect to a dead CDP endpoint. Please clear the CDP URL when shutting down cloud sessions to avoid this functional breakage.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: No reasoning provided

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 842:

<comment>After cleaning up the cloud browser you leave `browser_profile.cdp_url` pointing at the terminated session, so the next start skips provisioning and tries to reconnect to a dead CDP endpoint. Please clear the CDP URL when shutting down cloud sessions to avoid this functional breakage.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: No reasoning provided</comment>

<file context>
@@ -813,6 +834,16 @@ async def on_BrowserStopEvent(self, event: BrowserStopEvent) -&gt; None:
+				try:
+					from browser_use.browser.cloud import cleanup_cloud_client
+
+					await cleanup_cloud_client()
+					self.logger.info(&#39;🌤️ Cloud browser session cleaned up&#39;)
+				except Exception as e:
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_get_cdp_url:
mock_get_cdp_url.return_value = 'wss://test.proxy.daytona.works'

cdp_url = await mock_get_cdp_url()
Copy link

@cubic-staging cubic-staging bot Oct 6, 2025

Choose a reason for hiding this comment

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

This test never exercises get_cloud_browser_cdp_url—it calls the mock directly, so the helper could break without the test failing. Call the real function (which is patched) instead of invoking the mock to ensure coverage.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 253:

<comment>This test never exercises `get_cloud_browser_cdp_url`—it calls the mock directly, so the helper could break without the test failing. Call the real function (which is patched) instead of invoking the mock to ensure coverage.</comment>

<file context>
@@ -0,0 +1,333 @@
+		with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_get_cdp_url:
+			mock_get_cdp_url.return_value = &#39;wss://test.proxy.daytona.works&#39;
+
+			cdp_url = await mock_get_cdp_url()
+			assert cdp_url == &#39;wss://test.proxy.daytona.works&#39;
+			mock_get_cdp_url.assert_called_once()
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 10 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:514">
Marking cloud sessions as non-local prevents `reset()` from clearing the previous cloud `cdp_url`, so the next start skips provisioning a new browser and tries to reconnect to a stale CDP endpoint. Please clear the CDP URL when stopping cloud sessions so a fresh cloud browser is created on subsequent starts.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

try:
cloud_cdp_url = await get_cloud_browser_cdp_url()
self.browser_profile.cdp_url = cloud_cdp_url
self.browser_profile.is_local = False
Copy link

@cubic-staging cubic-staging bot Oct 6, 2025

Choose a reason for hiding this comment

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

Marking cloud sessions as non-local prevents reset() from clearing the previous cloud cdp_url, so the next start skips provisioning a new browser and tries to reconnect to a stale CDP endpoint. Please clear the CDP URL when stopping cloud sessions so a fresh cloud browser is created on subsequent starts.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 514:

<comment>Marking cloud sessions as non-local prevents `reset()` from clearing the previous cloud `cdp_url`, so the next start skips provisioning a new browser and tries to reconnect to a stale CDP endpoint. Please clear the CDP URL when stopping cloud sessions so a fresh cloud browser is created on subsequent starts.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+					try:
+						cloud_cdp_url = await get_cloud_browser_cdp_url()
+						self.browser_profile.cdp_url = cloud_cdp_url
+						self.browser_profile.is_local = False
+						self.logger.info(&#39;🌤️ Successfully connected to cloud browser service&#39;)
+					except CloudBrowserAuthError:
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 10 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="browser_use/dom/playground/extraction.py">

<violation number="1" location="browser_use/dom/playground/extraction.py:178">
Using unsupported tiktoken model alias raises KeyError and breaks the extraction loop.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:109">
Tracking only one global cloud session id causes concurrent sessions to stop the wrong browser and leaves earlier sessions running.</violation>

<violation number="2" location="browser_use/browser/cloud.py:227">
The use of a stateful global singleton for the `CloudBrowserClient` creates a race condition that leads to premature session termination and resource leaks when multiple cloud agents run concurrently. The client&#39;s lifecycle should be tied to the `BrowserSession` instance instead of being global.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:19">
Cloud stop leaves stale CDP URL cached, so the next start reuses a dead websocket and fails to reconnect.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

# pyperclip.copy(text_to_save)

encoding = tiktoken.encoding_for_model('gpt-4o')
encoding = tiktoken.encoding_for_model('gpt-4.1-mini')
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

Using unsupported tiktoken model alias raises KeyError and breaks the extraction loop.

Prompt for AI agents
Address the following comment on browser_use/dom/playground/extraction.py at line 178:

<comment>Using unsupported tiktoken model alias raises KeyError and breaks the extraction loop.</comment>

<file context>
@@ -175,7 +175,7 @@ def get_website_list_for_prompt() -&gt; str:
 				# pyperclip.copy(text_to_save)
 
-				encoding = tiktoken.encoding_for_model(&#39;gpt-4o&#39;)
+				encoding = tiktoken.encoding_for_model(&#39;gpt-4.1-mini&#39;)
 				token_count = len(encoding.encode(text_to_save))
 				print(f&#39;Token count: {token_count}&#39;)
</file context>

[internal] Confidence score: 6/10

[internal] Posted by: Functional Bugs Agent

Suggested change
encoding = tiktoken.encoding_for_model('gpt-4.1-mini')
encoding = tiktoken.encoding_for_model('gpt-4o')
Fix with Cubic



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

The use of a stateful global singleton for the CloudBrowserClient creates a race condition that leads to premature session termination and resource leaks when multiple cloud agents run concurrently. The client's lifecycle should be tied to the BrowserSession instance instead of being global.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>The use of a stateful global singleton for the `CloudBrowserClient` creates a race condition that leads to premature session termination and resource leaks when multiple cloud agents run concurrently. The client&#39;s lifecycle should be tied to the `BrowserSession` instance instead of being global.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

from uuid_extensions import uuid7str

from browser_use.browser.cloud import CloudBrowserAuthError, CloudBrowserError, get_cloud_browser_cdp_url

Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

Cloud stop leaves stale CDP URL cached, so the next start reuses a dead websocket and fails to reconnect.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 19:

<comment>Cloud stop leaves stale CDP URL cached, so the next start reuses a dead websocket and fails to reconnect.</comment>

<file context>
@@ -15,6 +15,8 @@
 from uuid_extensions import uuid7str
 
+from browser_use.browser.cloud import CloudBrowserAuthError, CloudBrowserError, get_cloud_browser_cdp_url
+
 # CDP logging is now handled by setup_logging() in logging_config.py
 # It automatically sets CDP logs to the same level as browser_use logs
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

browser_response = CloudBrowserResponse(**browser_data)

# Store session ID for cleanup
self.current_session_id = browser_response.id
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

Tracking only one global cloud session id causes concurrent sessions to stop the wrong browser and leaves earlier sessions running.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 109:

<comment>Tracking only one global cloud session id causes concurrent sessions to stop the wrong browser and leaves earlier sessions running.</comment>

<file context>
@@ -0,0 +1,286 @@
+			browser_response = CloudBrowserResponse(**browser_data)
+
+			# Store session ID for cleanup
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 10 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:513">
Sensitive data exposure: cloud CDP URL (likely contains auth token) is stored then logged/propagated, enabling unauthorized remote control (CWE-200, CWE-532).</violation>

<violation number="2" location="browser_use/browser/session.py:842">
After cleaning up the cloud browser client we still leave `browser_profile.cdp_url` pointing at the terminated session, so the next `start()` skips provisioning and connects to a dead endpoint. Please clear the cached CDP URL when the cloud session is torn down.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:112">
Sensitive data exposure: cdpUrl and liveUrl are logged, enabling session hijack if logs are exposed.</violation>

<violation number="2" location="browser_use/browser/cloud.py:227">
The use of a global singleton `_cloud_client` for a stateful resource is a critical architectural flaw. Because the client stores `current_session_id`, any concurrent `BrowserSession` instances with `cloud_browser=True` will conflict. This will cause one session&#39;s cleanup to incorrectly terminate another&#39;s browser, leading to resource leaks and broken application behavior.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

# Use cloud browser service
try:
cloud_cdp_url = await get_cloud_browser_cdp_url()
self.browser_profile.cdp_url = cloud_cdp_url
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

Sensitive data exposure: cloud CDP URL (likely contains auth token) is stored then logged/propagated, enabling unauthorized remote control (CWE-200, CWE-532).

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 513:

<comment>Sensitive data exposure: cloud CDP URL (likely contains auth token) is stored then logged/propagated, enabling unauthorized remote control (CWE-200, CWE-532).</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+					# Use cloud browser service
+					try:
+						cloud_cdp_url = await get_cloud_browser_cdp_url()
+						self.browser_profile.cdp_url = cloud_cdp_url
+						self.browser_profile.is_local = False
+						self.logger.info(&#39;🌤️ Successfully connected to cloud browser service&#39;)
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

Sensitive data exposure: cdpUrl and liveUrl are logged, enabling session hijack if logs are exposed.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Sensitive data exposure: cdpUrl and liveUrl are logged, enabling session hijack if logs are exposed.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic



# Global client instance
_cloud_client: CloudBrowserClient | None = None
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

The use of a global singleton _cloud_client for a stateful resource is a critical architectural flaw. Because the client stores current_session_id, any concurrent BrowserSession instances with cloud_browser=True will conflict. This will cause one session's cleanup to incorrectly terminate another's browser, leading to resource leaks and broken application behavior.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 227:

<comment>The use of a global singleton `_cloud_client` for a stateful resource is a critical architectural flaw. Because the client stores `current_session_id`, any concurrent `BrowserSession` instances with `cloud_browser=True` will conflict. This will cause one session&#39;s cleanup to incorrectly terminate another&#39;s browser, leading to resource leaks and broken application behavior.</comment>

<file context>
@@ -0,0 +1,286 @@
+
+
+# Global client instance
+_cloud_client: CloudBrowserClient | None = None
+
+
</file context>

[internal] Confidence score: 10/10

[internal] Posted by: System Design Agent

Fix with Cubic

try:
from browser_use.browser.cloud import cleanup_cloud_client

await cleanup_cloud_client()
Copy link

@cubic-staging cubic-staging bot Oct 9, 2025

Choose a reason for hiding this comment

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

After cleaning up the cloud browser client we still leave browser_profile.cdp_url pointing at the terminated session, so the next start() skips provisioning and connects to a dead endpoint. Please clear the cached CDP URL when the cloud session is torn down.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 842:

<comment>After cleaning up the cloud browser client we still leave `browser_profile.cdp_url` pointing at the terminated session, so the next `start()` skips provisioning and connects to a dead endpoint. Please clear the cached CDP URL when the cloud session is torn down.</comment>

<file context>
@@ -813,6 +834,16 @@ async def on_BrowserStopEvent(self, event: BrowserStopEvent) -&gt; None:
+				try:
+					from browser_use.browser.cloud import cleanup_cloud_client
+
+					await cleanup_cloud_client()
+					self.logger.info(&#39;🌤️ Cloud browser session cleaned up&#39;)
+				except Exception as e:
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

Copy link

@cubic-staging cubic-staging bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 10 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="docs/customize/browser/remote.mdx">

<violation number="1" location="docs/customize/browser/remote.mdx:37">
Missing comma between keyword arguments in the proxy example causes a SyntaxError when users run the documented code.</violation>
</file>

<file name="browser_use/browser/cloud.py">

<violation number="1" location="browser_use/browser/cloud.py:112">
Sensitive data exposure: logging CDP URL can leak attach token/session endpoint enabling unauthorized browser control.</violation>
</file>

<file name="browser_use/browser/session.py">

<violation number="1" location="browser_use/browser/session.py:509">
Cloud browser cleanup leaves the old CDP URL cached, so the next start reuses a dead endpoint instead of provisioning a fresh cloud browser. Please reset `browser_profile.cdp_url` after cleanup so future starts re-provision correctly.</violation>
</file>

<file name="tests/ci/test_cloud_browser.py">

<violation number="1" location="tests/ci/test_cloud_browser.py:294">
The mocked CloudBrowserAuthError message omits the expected hint, so the following assertion inevitably fails; update the side_effect message to include the required text.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: In the test, `get_cloud_browser_cdp_url` is imported directly from `browser_use.browser.cloud`. When the test enters the `with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;)` block, the patch replaces the attribute in the original module but does not affect the already imported local reference. Therefore the call to `await get_cloud_browser_cdp_url()` executes the real function, which raises a `CloudBrowserAuthError` whose message already contains the expected &quot;BROWSER_USE_API_KEY environment variable&quot; substring. The mocked `side_effect` string is never used, so the assertion does not inevitably fail. The reported issue is incorrect.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

# Use Browser-Use cloud browser service
browser = Browser(
cloud_browser=True # Automatically provisions a cloud browser
)
Copy link

@cubic-staging cubic-staging bot Oct 15, 2025

Choose a reason for hiding this comment

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

Missing comma between keyword arguments in the proxy example causes a SyntaxError when users run the documented code.

Prompt for AI agents
Address the following comment on docs/customize/browser/remote.mdx at line 37:

<comment>Missing comma between keyword arguments in the proxy example causes a SyntaxError when users run the documented code.</comment>

<file context>
@@ -23,8 +23,39 @@ agent = Agent(
+# Use Browser-Use cloud browser service
+browser = Browser(
+    cloud_browser=True  # Automatically provisions a cloud browser
+)
+
+agent = Agent(
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Suggested change
)
),
Fix with Cubic

self.current_session_id = browser_response.id

logger.info(f'🌤️ Cloud browser created successfully: {browser_response.id}')
logger.debug(f'🌤️ CDP URL: {browser_response.cdpUrl}')
Copy link

@cubic-staging cubic-staging bot Oct 15, 2025

Choose a reason for hiding this comment

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

Sensitive data exposure: logging CDP URL can leak attach token/session endpoint enabling unauthorized browser control.

Prompt for AI agents
Address the following comment on browser_use/browser/cloud.py at line 112:

<comment>Sensitive data exposure: logging CDP URL can leak attach token/session endpoint enabling unauthorized browser control.</comment>

<file context>
@@ -0,0 +1,286 @@
+			self.current_session_id = browser_response.id
+
+			logger.info(f&#39;🌤️ Cloud browser created successfully: {browser_response.id}&#39;)
+			logger.debug(f&#39;🌤️ CDP URL: {browser_response.cdpUrl}&#39;)
+			logger.debug(f&#39;🌤️ Live URL: {browser_response.liveUrl}&#39;)
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Security Vulnerabilities Agent

Fix with Cubic

# If no CDP URL, launch local browser or cloud browser
if not self.cdp_url:
if self.is_local:
if self.browser_profile.cloud_browser:
Copy link

@cubic-staging cubic-staging bot Oct 15, 2025

Choose a reason for hiding this comment

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

Cloud browser cleanup leaves the old CDP URL cached, so the next start reuses a dead endpoint instead of provisioning a fresh cloud browser. Please reset browser_profile.cdp_url after cleanup so future starts re-provision correctly.

Prompt for AI agents
Address the following comment on browser_use/browser/session.py at line 509:

<comment>Cloud browser cleanup leaves the old CDP URL cached, so the next start reuses a dead endpoint instead of provisioning a fresh cloud browser. Please reset `browser_profile.cdp_url` after cleanup so future starts re-provision correctly.</comment>

<file context>
@@ -496,9 +504,22 @@ async def on_BrowserStartEvent(self, event: BrowserStartEvent) -&gt; dict[str, str]
+			# If no CDP URL, launch local browser or cloud browser
 			if not self.cdp_url:
-				if self.is_local:
+				if self.browser_profile.cloud_browser:
+					# Use cloud browser service
+					try:
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Suggested change
if self.browser_profile.cloud_browser:
if self.browser_profile.cloud_browser:
self.browser_profile.cdp_url = None
Fix with Cubic


# Test that cloud browser client raises error without fallback
with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') as mock_cloud_cdp:
mock_cloud_cdp.side_effect = CloudBrowserAuthError('No auth token')
Copy link

@cubic-staging cubic-staging bot Oct 15, 2025

Choose a reason for hiding this comment

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

The mocked CloudBrowserAuthError message omits the expected hint, so the following assertion inevitably fails; update the side_effect message to include the required text.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: In the test, get_cloud_browser_cdp_url is imported directly from browser_use.browser.cloud. When the test enters the with patch('browser_use.browser.cloud.get_cloud_browser_cdp_url') block, the patch replaces the attribute in the original module but does not affect the already imported local reference. Therefore the call to await get_cloud_browser_cdp_url() executes the real function, which raises a CloudBrowserAuthError whose message already contains the expected "BROWSER_USE_API_KEY environment variable" substring. The mocked side_effect string is never used, so the assertion does not inevitably fail. The reported issue is incorrect.

Prompt for AI agents
Address the following comment on tests/ci/test_cloud_browser.py at line 294:

<comment>The mocked CloudBrowserAuthError message omits the expected hint, so the following assertion inevitably fails; update the side_effect message to include the required text.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: In the test, `get_cloud_browser_cdp_url` is imported directly from `browser_use.browser.cloud`. When the test enters the `with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;)` block, the patch replaces the attribute in the original module but does not affect the already imported local reference. Therefore the call to `await get_cloud_browser_cdp_url()` executes the real function, which raises a `CloudBrowserAuthError` whose message already contains the expected &quot;BROWSER_USE_API_KEY environment variable&quot; substring. The mocked `side_effect` string is never used, so the assertion does not inevitably fail. The reported issue is incorrect.</comment>

<file context>
@@ -0,0 +1,333 @@
+
+	# Test that cloud browser client raises error without fallback
+	with patch(&#39;browser_use.browser.cloud.get_cloud_browser_cdp_url&#39;) as mock_cloud_cdp:
+		mock_cloud_cdp.side_effect = CloudBrowserAuthError(&#39;No auth token&#39;)
+
+		# Verify that the cloud browser client raises the expected error
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Fix with Cubic

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.

2 participants