browser-use/browser-use · error · ValueError
Must provide either browser_session or both dom_service and
Error message
Must provide either browser_session or both dom_service and target_id
What it means
The mirror-image validation of error 166: the extractor requires at least one complete input source — a browser_session, or both dom_service AND target_id. This fires when neither is given, or when only one of dom_service/target_id is supplied (a DOM service handle without a target id, or a target id without a service). The two arguments of the actor path are meaningless alone, so the call is rejected.
Source
Thrown at browser_use/dom/markdown_extractor.py:63
Raises:
ValueError: If neither browser_session nor (dom_service + target_id) are provided
"""
# Validate input parameters
if browser_session is not None:
if dom_service is not None or target_id is not None:
raise ValueError('Cannot specify both browser_session and dom_service/target_id')
# Browser session path (tools service)
enhanced_dom_tree = await _get_enhanced_dom_tree_from_browser_session(browser_session)
current_url = await browser_session.get_current_page_url()
method = 'enhanced_dom_tree'
elif dom_service is not None and target_id is not None:
# DOM service path (page actor)
# Lazy fetch all_frames inside get_dom_tree if needed (for cross-origin iframes)
enhanced_dom_tree, _ = await dom_service.get_dom_tree(target_id=target_id, all_frames=None)
current_url = None # Not available via DOM service
method = 'dom_service'
else:
raise ValueError('Must provide either browser_session or both dom_service and target_id')
# Use the HTML serializer with the enhanced DOM tree
html_serializer = HTMLSerializer(extract_links=extract_links)
page_html = html_serializer.serialize(enhanced_dom_tree)
original_html_length = len(page_html)
content, initial_markdown_length, chars_filtered = convert_html_to_markdown(page_html, extract_images=extract_images)
final_filtered_length = len(content)
# Content statistics
stats = {
'method': method,
'original_html_chars': original_html_length,
'initial_markdown_chars': initial_markdown_length,
'filtered_chars_removed': chars_filtered,
'final_filtered_chars': final_filtered_length,View on GitHub (pinned to 6c73fced2f)
Solutions
- If you have a browser session, pass browser_session
- If you use the DOM-service path, always pass dom_service AND target_id together
- Guard upstream: skip the call when target_id is None instead of forwarding it
Example fix
# before
md = await markdown_extractor.extract_markdown(dom_service=svc, target_id=None)
# after
if tid is None:
return
md = await markdown_extractor.extract_markdown(dom_service=svc, target_id=tid) Defensive patterns
Strategy: validation
Validate before calling
if browser_session is None and (dom_service is None or target_id is None):
raise ValueError('provide browser_session, or both dom_service and target_id, before calling') Type guard
def extractor_args_valid(browser_session=None, dom_service=None, target_id=None) -> bool:
if browser_session is not None:
return dom_service is None and target_id is None
return dom_service is not None and target_id is not None Try / catch
try:
md = await markdown_extractor.extract_markdown(dom_service=svc, target_id=tid)
except ValueError as e:
if 'Must provide' in str(e):
tid = await resolve_target_id() # backfill the missing piece and retry
md = await markdown_extractor.extract_markdown(dom_service=svc, target_id=tid)
else:
raise Prevention
- Never forward possibly-None target_id; skip or resolve it first
- Assert argument completeness in wrapper functions before calling the extractor
- Unit-test wrappers with None branches to catch partial-argument paths early
When it happens
Trigger: Calling the extractor with no arguments; passing target_id but forgetting dom_service (or vice versa) after refactoring; passing None explicitly because upstream lookups returned None.
Common situations: Optional chaining where the caller does extract_markdown(dom_service=svc, target_id=maybe_none) and maybe_none is None on some pages; forgetting to await the session creation before calling.
Related errors
- Cannot specify both browser_session and dom_service/target_i
- Cannot specify both "browser" and "browser_session" paramete
- Cannot specify both "skills" and "skill_ids" parameters. Use
- Cannot provide both file_system_state (from agent state) and
- Set trigger_char_count or trigger_token_count, not both.
AI-assisted analysis of browser-use/browser-use@6c73fced2f (2026-08-14).
Data as JSON: /api/errors/d4f2d2a36820b52b.
Report an issue: GitHub.