# NousResearch/hermes-agent · Error handling for browser provider network calls

## Open now

- Nothing open on GitHub.

A bug report and corresponding fixes addressing unprotected network calls in browser providers that crash when a connection failure occurs. The fix wraps these calls with error handling to prevent crashes.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #26247. Verify it addresses your case.
- **Recommended:** read PR #26247 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-26247`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #2746: \[Bug\]: Unprotected network calls in browser providers crash on connection failure

## Prior & competing PRs

- **#2753: fix(tools): wrap browser provider network calls with error handling**. closed without merge · fix tier `suggested`
  - maintainer direction: category `uncategorized`; implication `needs_llm`; refs `#26247`
  - _suggested-tier fix detail withheld; re-request with `?tier=all` to include it._
- **#26247: fix(tools): wrap browser provider network calls with error handling**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `tools/browser_providers/browser_use.py`, `tools/browser_providers/browserbase.py`, `tools/browser_providers/firecrawl.py`
  - fix hunks:
  - `tools/browser_providers/browser_use.py`

    ```diff
    @@ -137,12 +137,22 @@ def create_session(self, task_id: str) -> Dict[str, object]:
                 else {}
             )
     
    -        response = requests.post(
    -            f"{config['base_url']}/browsers",
    -            headers=headers,
    -            json=payload,
    -            timeout=30,
    -        )
    +        try:
    +            response = requests.post(
    +                f"{config['base_url']}/browsers",
    +                headers=headers,
    +                json=payload,
    +                timeout=30,
    +            )
    +        except requests.RequestException as exc:
    +            # Managed mode: propagate raw so callers can retry with the
    +            # preserved idempotency key. Direct mode: wrap network failures
    +            # into a clean RuntimeError for end users.
    +            if managed_mode:
    +                raise
    +            raise RuntimeError(
    +                f"Browser Use API connection failed: {exc}"
    +            ) from exc
     
             if not response.ok:
                 if managed_mode and not _should_preserve_pending_create_key(response):
    ```
  - `tools/browser_providers/browserbase.py`

    ```diff
    @@ -92,45 +92,50 @@ def create_session(self, task_id: str) -> Dict[str, object]:
                 "X-BB-API-Key": [redacted:secret-assignment]"api_key"],
             }
     
    -        response = requests.post(
    -            f"{config['base_url']}/v1/sessions",
    -            headers=headers,
    -            json=session_config,
    -            timeout=30,
    -        )
    -
    -        proxies_fallback = False
    -        keepalive_fallback = False
    -
    -        # Handle 402 — paid features unavailable
    -        if response.status_code == 402:
    -            if enable_keep_alive:
    -                keepalive_fallback = True
    -                logger.warning(
    -                    "keepAlive may require paid plan (402), retrying without it. "
    -                    "Sessions may timeout during long operations."
    -                )
    -                session_config.pop("keepAlive", None)
    -                response = requests.post(
    -                    f"{config['base_url']}/v1/sessions",
    -                    headers=headers,
    -                    json=session_config,
    -                    timeout=30,
    -                )
    +        try:
    +            response = requests.post(
    +                f"{config['base_url']}/v1/sessions",
    +                headers=headers,
    +                json=session_config,
    +                timeout=30,
    +            )
     
    -            if response.status_code == 402 and enable_proxies:
    -                proxies_fallback = True
    -                logger.warning(
    -                    "Proxies unavailable (402), retrying without proxies. "
    -                    "Bot detection may be less effective."
    -                )
    -                session_config.pop("proxies", None)
    -                response = requests.post(
    -                    f"{config['base_url']}/v1/sessions",
    -                    headers=headers,
    -                    json=session_config,
    -                    timeout=30,
    -                )
    +            proxies_fallback = False
    +            keepalive_fallback = False
    +
    +            # Handle 402 — paid features unavailable
    +            if response.status_code == 402:
    +                if enable_keep_alive:
    +                    keepalive_fallback = True
    +                    logger.warning(
    +                        "keepAlive may require paid plan (402), retrying without it. "
    +                        "Sessions may timeout during long operations."
    +                    )
    +                    session_config.pop("keepAlive", None)
    +                    response = requests.post(
    +                        f"{config['base_url']}/v1/sessions",
    +                        headers=headers,
    +                        json=session_config,
    +                        timeout=30,
    +                    )
    +
    +                if response.status_code == 402 and enable_proxies:
    +                    proxies_fallback = True
    +                    logger.warning(
    +                        "Proxies unavailable (402), retrying without proxies. "
    +                        "Bot detection may be less effective."
    +                    )
    +                    session_config.pop("proxies", None)
    +                    response = requests.post(
    +                        f"{config['base_url']}/v1/sessions",
    +                        headers=headers,
    +                        json=session_config,
    +                        timeout=30,
    +                    )
    +        except requests.RequestException as exc:
    +            raise RuntimeError(
    +                f"Browserbase API connection failed: {exc}"
    +            ) from exc
     
             if not response.ok:
                 raise RuntimeError(
    ```
  - `tools/browser_providers/firecrawl.py`

    ```diff
    @@ -47,12 +47,17 @@ def create_session(self, task_id: str) -> Dict[str, object]:
     
             body: Dict[str, object] = {"ttl": ttl}
     
    -        response = requests.post(
    -            f"{self._api_url()}/v2/browser",
    -            headers=self._headers(),
    -            json=body,
    -            timeout=30,
    -        )
    +        try:
    +            response = requests.post(
    +                f"{self._api_url()}/v2/browser",
    +                headers=self._headers(),
    +                json=body,
    +                timeout=30,
    +            )
    +        except requests.RequestException as exc:
    +            raise RuntimeError(
    +                f"Firecrawl API connection failed: {exc}"
    +            ) from exc
     
             if not response.ok:
                 raise RuntimeError(
    ```

## Fix status

- Merged to main in PR #26247 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-05-15`.
- Subsystem: `agent`
