crewAIInc/crewAI · error · ValueError

URL cannot be empty

Error message

URL cannot be empty

What it means

ValueError raised by SeleniumScrapingTool._make_request when the url argument is falsy (None or empty string). _make_request is the navigation step of _run; the schema validator already blocks empty URLs at construction, so this guard mainly catches the code path where _run was called without a website_url and the internal default is unset. It fails before the browser navigates anywhere.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/selenium_scraping_tool/selenium_scraping_tool.py:193

    def _get_elements_content(
        self, css_element: str | None, return_html: bool | None
    ) -> list[str]:
        if self.driver is None or self._by is None:
            raise RuntimeError("Driver not initialized. Call _run first.")
        elements_content: list[str] = []

        for element in self.driver.find_elements(self._by.CSS_SELECTOR, css_element):
            elements_content.append(  # noqa: PERF401
                element.get_attribute("outerHTML") if return_html else element.text
            )

        return elements_content

    def _make_request(
        self, url: str | None, cookie: dict[str, Any] | None, wait_time: int | None
    ) -> None:
        if not url:
            raise ValueError("URL cannot be empty")

        if not re.match(r"^https?://", url):
            raise ValueError("URL must start with http:// or https://")

        if self.driver is None:
            raise RuntimeError("Driver not initialized. Call _run first.")
        sleep_time = wait_time or 0
        self.driver.get(url)
        time.sleep(sleep_time)
        if cookie:
            self.driver.add_cookie(cookie)
            time.sleep(sleep_time)
            self.driver.get(url)
            time.sleep(sleep_time)

    def close(self) -> None:
        if self.driver is not None:
            self.driver.close()

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass the URL: SeleniumScrapingTool(website_url='https://example.com', css_element='article') or tool.run('https://example.com').
  2. Default the URL variable early: url = url or FALLBACK_URL before invoking the tool.
  3. Fail fast in your orchestration code when a required URL is missing.

Example fix

# before
result = tool.run()  # no url anywhere -> ValueError: URL cannot be empty

# after
result = tool.run("https://example.com")
Defensive patterns

Strategy: validation

Validate before calling

if not url or not url.strip():
    raise ValueError("a website_url must be supplied to SeleniumScrapingTool")
result = tool.run(url.strip())

Try / catch

try:
    result = tool.run()
except ValueError as e:
    if "cannot be empty" in str(e):
        result = tool.run(DEFAULT_URL)
    else:
        raise

Prevention

When it happens

Trigger: Calling the tool with no website_url provided anywhere (neither constructor nor run kwargs) so _make_request receives None; internal/direct calls to _make_request with an empty url.

Common situations: Instantiating SeleniumScrapingTool() bare and calling run() expecting the agent to always supply the URL, but it doesn't; dynamic flows where the URL variable is conditionally assigned and ends up None.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/2bd2ec96f36a653f. Report an issue: GitHub.