#14728: fix(browser): add targetUrl description and improve error messages (#14700)
agents
stale
size: S
trusted-contributor
Cluster:
Error Handling Improvements
## Summary
- **Bug**: Browser tool schema marks `targetUrl` as `Optional`, but runtime requires it for `open`/`navigate` actions. Models (especially Gemini 3 Flash) omit it, get a generic `"targetUrl required"` error, and enter infinite tool-call loops lasting up to 10 minutes.
- **Root cause**: `browser-tool.schema.ts` defines `targetUrl: Type.Optional(Type.String())` with no description. `browser-tool.ts` reads it with `{ required: true }` for `open`/`navigate`. The model sees optional in schema, omits it, gets unhelpful error, retries identically.
- **Fix**: Add a description to the schema field explaining `targetUrl` is required for `open`/`navigate`, and improve runtime error messages to include the action name.
Fixes #14700
## Problem
The browser tool uses a flat schema (all actions share one `Type.Object`). `targetUrl` is `Type.Optional` because most actions don't need it, but `open` and `navigate` require it at runtime via `readStringParam(params, "targetUrl", { required: true })`.
When a model calls `browser(action="open")` without `targetUrl`, the error is just `"targetUrl required"` — no mention of which action or what to provide. The model sees the schema says optional, doesn't understand the error, and retries with the same params indefinitely.
**Before fix (reproduced on main via integration test):**
```
pnpm vitest run src/agents/tools/_repro-14700.test.ts
✓ schema has no description on targetUrl to guide the model
→ descriptions = [] (length 0)
✓ runtime throws generic 'targetUrl required' without mentioning the action
→ Error: "targetUrl required" (no mention of open/navigate)
Test Files 1 passed (1)
Tests 2 passed (2)
```
## Changes
- `src/agents/tools/browser-tool.schema.ts` — Add `description: "URL to open or navigate to. Required for open and navigate actions."` to the `targetUrl` field
- `src/agents/tools/browser-tool.ts` — Use descriptive `label` in `readStringParam` for `open` and `navigate` actions so error messages include the action name (e.g. `"targetUrl is required for the open action — provide the URL to open"`)
- `src/agents/tools/browser-tool.targeturl-schema.test.ts` — New regression tests: verify schema description exists and runtime errors mention action names
- `CHANGELOG.md` — Add fix entry
**After fix (verified on fix branch):**
```
pnpm vitest run src/agents/tools/browser-tool.targeturl-schema.test.ts
✓ schema targetUrl has description guiding the model
✓ runtime error for open action mentions the action name
✓ runtime error for navigate action mentions the action name
Test Files 1 passed (1)
Tests 3 passed (3)
```
## Design decisions
- **Keep `targetUrl` as Optional in schema**: The flat schema is shared across all actions. Making it required would force `status`, `tabs`, `snapshot` etc. to also provide a URL. Instead, the description tells the model when it's needed.
- **Description + better error message (dual approach)**: Description prevents the model from omitting `targetUrl` in the first place. Improved error message helps recovery if it still does.
## Test plan
- [x] New test: schema `targetUrl` has description mentioning `open`/`navigate`
- [x] New test: runtime error for `open` action includes action name
- [x] New test: runtime error for `navigate` action includes action name
- [x] All 12 existing browser-tool tests pass (`pnpm vitest run src/agents/tools/browser-tool.test.ts`)
- [x] Lint passes (`pnpm lint`)
- [x] Bug reproduced on main: no description, generic error message (integration test)
- [x] Fix verified on fix branch: description present, descriptive errors (integration test)
## Effect on User Experience
**Before:** Models (especially Gemini 3 Flash) enter infinite tool-call loops when using browser `open`/`navigate` without `targetUrl`. Agent becomes unresponsive for up to 10 minutes, wastes API quota.
**After:** Schema description guides models to include `targetUrl` for `open`/`navigate`. If still omitted, the error message clearly states which action requires it and what to provide, enabling model self-correction.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR improves the browser tool’s guidance and error surfaces around `targetUrl` by (1) adding a schema description indicating it’s required for the `open` and `navigate` actions, and (2) providing more descriptive `readStringParam` labels so missing-parameter errors include the relevant action. It also adds a small Vitest regression suite to prevent the schema/behavior mismatch from reappearing and records the fix in the changelog.
Within the codebase, `BrowserToolSchema` (TypeBox) remains intentionally flattened to satisfy tool-schema constraints, while `browser-tool.ts` continues to enforce per-action runtime requirements; these changes make that runtime contract clearer to both models and developers.
<h3>Confidence Score: 4/5</h3>
- This PR is largely safe to merge; it primarily adds schema metadata, clearer errors, and a regression test.
- Reviewed the changed schema, runtime usage, and the shared `readStringParam` implementation. The runtime change is localized and low-risk. The only actionable issue found is that one new regression assertion doesn’t actually protect the stated requirement for both `open` and `navigate`, reducing the test’s value.
- src/agents/tools/browser-tool.targeturl-schema.test.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#23075: fix(browser): merge top-level ref/targetId into act request body
by Remixer33 · 2026-02-22
78.1%
#23668: fix: distinguish browser validation errors from connectivity failures
by davidemanuelDEV · 2026-02-22
76.6%
#12642: feat(tools): typed tool schemas for xAI/Grok compatibility
by 2nd-ren · 2026-02-09
76.3%
#22214: fix(tools): sanitize google-antigravity schemas for Gemini-compatib...
by Kansodata · 2026-02-20
76.1%
#12378: feat: expose download and waitForDownload actions in browser agent ...
by vabole · 2026-02-09
75.9%
#3794: fix(browser-tool): disallow close without targetId to avoid unsafe ...
by JaydenLiang · 2026-01-29
75.8%
#15071: fix(browser): default fill field type to textbox when omitted
by Ayush10 · 2026-02-12
73.9%
#18907: Fix: Improve browser error messages to avoid misleading agents
by jriff · 2026-02-17
73.2%
#22952: fix(browser): suggest remote profile when local Chrome is not insta...
by dashed · 2026-02-21
73.1%
#18888: Fix: Merge targetId into request body for browser act operations
by jriff · 2026-02-17
73.0%