#23668: fix: distinguish browser validation errors from connectivity failures
size: XS
Cluster:
Error Handling Improvements
## Problem
Fixes #23552
When the browser control service returns a 4xx validation error (e.g. `"fields are required"` for an invalid `fill` action), `enhanceBrowserFetchError` wraps ALL errors as:
> Can't reach the OpenClaw browser control service. Do NOT retry...
This is misleading — the browser IS reachable, the request was just invalid. The model then gives up entirely instead of adjusting its parameters.
This particularly affects GPT-5.2 which sends browser tool params that fail schema validation. The model sees "browser unavailable" and stops trying, when it should see "bad request, fix your params."
## Fix
1. **Preserve HTTP status on fetch errors** — when `fetchHttpJson` gets a non-OK response, attach the status code to the thrown error
2. **Check for 4xx in `enhanceBrowserFetchError`** — return an actionable validation error message instead of a connectivity failure message
### Before (GPT-5.2 sees):
```
Can't reach the OpenClaw browser control service.
Do NOT retry the browser tool — it will keep failing.
(Error: fields are required)
```
### After:
```
Browser tool request failed (HTTP 400): fields are required.
Check that the tool parameters match the expected schema.
Try a different approach or simplify the request.
```
The model can now distinguish "my request was wrong" from "the browser is down" and adjust accordingly.
## Notes
The underlying GPT-5.2 schema compatibility issue (why it sends invalid `fill` params) is separate and may need a schema adjustment or model-specific workaround. This PR ensures the error reporting is accurate regardless.
---
*This PR was AI-assisted (per CONTRIBUTING.md guidelines).*
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Improves error messaging for browser validation errors (4xx) vs connectivity failures by preserving HTTP status codes and providing actionable feedback to the model. The fix correctly handles the HTTP fetch path but misses the local dispatcher path where 4xx errors are also thrown without the `httpStatus` property, resulting in incomplete coverage.
<h3>Confidence Score: 3/5</h3>
- Safe to merge with one logical issue requiring a fix
- The implementation correctly handles HTTP fetch errors but has incomplete coverage - local dispatcher 4xx errors won't receive the improved error messaging, defeating part of the PR's purpose for non-HTTP browser control requests
- Fix the local dispatcher error path in `src/browser/client-fetch.ts` (line 260-265) to attach `httpStatus` property
<sub>Last reviewed commit: 55a3c4a</sub>
<!-- greptile_other_comments_section -->
<sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#18907: Fix: Improve browser error messages to avoid misleading agents
by jriff · 2026-02-17
84.2%
#14784: fix(browser): clarify stale targetId errors (tab not found)
by sovushik · 2026-02-12
79.8%
#14728: fix(browser): add targetUrl description and improve error messages ...
by lailoo · 2026-02-12
76.6%
#23075: fix(browser): merge top-level ref/targetId into act request body
by Remixer33 · 2026-02-22
75.4%
#21017: fix: treat HTTP 502/503/504 as failover-eligible (timeout reason)
by taw0002 · 2026-02-19
74.1%
#9427: fix: trigger model fallback on all 4xx HTTP errors
by dbottme · 2026-02-05
74.0%
#14944: fix(browser): prefer openclaw profile in headless/noSandbox environ...
by BenediktSchackenberg · 2026-02-12
73.8%
#21638: fix(models): surface models.json validation errors instead of faili...
by aldoeliacim · 2026-02-20
73.7%
#10367: CLI/Ops: resilient browser fill + failover hardening + operations t...
by cluster2600 · 2026-02-06
73.7%
#9173: Fix: Improve error messaging for API rate limits and billing errors
by vishaltandale00 · 2026-02-04
73.6%