crewAIInc/crewAI · warning · ValueError
URL scheme must be 'http' or 'https'
Error message
URL scheme must be 'http' or 'https'
What it means
A ValueError raised by the sync NavigateBrowserTool._run when the target URL's scheme is neither http nor https (checked via urlparse). It is then caught by the method's own `except Exception` and returned as the string "Error navigating to <url>: URL scheme must be 'http' or 'https'" rather than propagated — so callers see an error string, not an exception.
Source
Thrown at lib/crewai-tools/src/crewai_tools/aws/bedrock/browser/browser_toolkit.py:142
return False
# Tool classes
class NavigateTool(BrowserBaseTool):
"""Tool for navigating a browser to a URL."""
name: str = "navigate_browser"
description: str = "Navigate a browser to the specified URL"
args_schema: type[BaseModel] = NavigateToolInput
def _run(self, url: str, thread_id: str = "default", **kwargs: Any) -> str:
"""Use the sync tool."""
try:
page = self.get_sync_page(thread_id)
parsed_url = urlparse(url)
if parsed_url.scheme not in ("http", "https"):
raise ValueError("URL scheme must be 'http' or 'https'")
# Navigate to URL
response = page.goto(url)
status = response.status if response else "unknown"
return f"Navigating to {url} returned status code {status}"
except Exception as e:
return f"Error navigating to {url}: {e!s}"
async def _arun(self, url: str, thread_id: str = "default", **kwargs: Any) -> str:
"""Use the async tool."""
try:
page = await self.get_async_page(thread_id)
parsed_url = urlparse(url)
if parsed_url.scheme not in ("http", "https"):
raise ValueError("URL scheme must be 'http' or 'https'")
# Navigate to URLView on GitHub (pinned to 754d7323be)
Solutions
- Normalize URLs before invoking: prepend 'https://' when the scheme is missing.
- Reject non-http(s) input upstream (validate user/LLM URL output) — the tool intentionally blocks file:, ftp:, javascript:.
- If you need local files, serve them over a local http server instead of file://.
Example fix
# before
result = navigate_tool._run(url="example.com")
# after
from urllib.parse import urlparse
def ensure_scheme(url: str) -> str:
return url if urlparse(url).scheme in ("http", "https") else f"https://{url}"
result = navigate_tool._run(url=ensure_scheme("example.com")) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def normalize_url(url: str) -> str | None:
url = url.strip()
if not url:
return None
if urlparse(url).scheme not in ("http", "https"):
url = "https://" + url.lstrip("/")
return url if urlparse(url).scheme in ("http", "https") else None Type guard
def is_navigable_url(url: str) -> bool:
return urlparse(url).scheme in ("http", "https") Try / catch
# The tool returns error strings instead of raising — check the return value:
result = navigate_tool._run(url=url)
if result.startswith("Error navigating"):
url = f"https://{url}" # or log/skip
result = navigate_tool._run(url=url) Prevention
- Normalize LLM-generated URLs (prepend https:// when scheme is missing) before tool calls.
- Treat returned 'Error navigating to ...' strings as failures in orchestration logic.
- Never feed raw user input or file:// URLs to the browser toolkit.
When it happens
Trigger: Calling the navigate_browser tool with URLs like 'ftp://example.com', 'file:///etc/passwd', 'chrome://settings', or with no scheme at all ('example.com' parses with scheme=''), or javascript: URLs from an LLM.
Common situations: An LLM agent passing a bare domain without https://; malicious or malformed URLs from user input reaching the browser tool; attempts to use file:// or internal chrome:// schemes which the toolkit deliberately blocks as a safety measure.
Related errors
- agent_id cannot be empty
- agent_id must be a string
- agent_alias_id cannot be empty
- agent_alias_id must be a string
- session_id must be a string
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/4dc921d6ed93e907.
Report an issue: GitHub.