crewAIInc/crewAI · error · ValueError

Query is required

Error message

Query is required

What it means

Raised by BraveSearchTool._run when no search query can be resolved. The method falls back across three keyword names — q, then query, then search_query — and if all are missing/empty it raises this ValueError before any HTTP call is made.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/brave_search_tool/brave_search_tool.py:75

                "BRAVE_API_KEY environment variable is required for BraveSearchTool"
            )

    def _run(
        self,
        **kwargs: Any,
    ) -> Any:
        current_time = time.time()
        if (current_time - self._last_request_time) < self._min_request_interval:
            time.sleep(
                self._min_request_interval - (current_time - self._last_request_time)
            )
        BraveSearchTool._last_request_time = time.time()

        try:
            # Fallback to "query" or "search_query" for backwards compatibility
            query = kwargs.get("q") or kwargs.get("query") or kwargs.get("search_query")
            if not query:
                raise ValueError("Query is required")

            payload = {"q": query}

            if country := kwargs.get("country"):
                payload["country"] = country

            # Fallback to "search_language" for backwards compatibility
            if search_lang := kwargs.get("search_lang") or kwargs.get(
                "search_language"
            ):
                payload["search_lang"] = search_lang

            # Fallback to deprecated n_results parameter if no count is provided
            count = kwargs.get("count")
            if count is not None:
                payload["count"] = count
            else:
                payload["count"] = self.n_results

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass the query under one of the accepted names: q, query, or search_query.
  2. Prefer positional invocation: tool.run('best crewai tutorials') which maps to q.
  3. If an agent generates the call, tighten the tool's description/backstory so it always supplies the query parameter.
  4. Guard the input: reject empty or whitespace-only strings before invoking the tool.

Example fix

# before
result = tool.run(count=5)  # ValueError: Query is required

# after
result = tool.run(q='crewai tutorials', count=5)
Defensive patterns

Strategy: validation

Validate before calling

def clean_query(q=None, query=None, search_query=None):
    value = q or query or search_query
    if not value or not value.strip():
        raise ValueError("Query is required")
    return value.strip()

query = clean_query(**tool_kwargs)
result = tool.run(q=query)

Type guard

def has_valid_query(kwargs: dict) -> bool:
    v = kwargs.get("q") or kwargs.get("query") or kwargs.get("search_query")
    return isinstance(v, str) and bool(v.strip())

Try / catch

try:
    result = tool.run(q=query)
except ValueError as e:
    if str(e) == "Query is required":
        # regenerate/repair the query, then retry once
        query = fallback_query_from_context()
        result = tool.run(q=query)
    else:
        raise

Prevention

When it happens

Trigger: Calling tool.run() with no arguments; calling tool.run(query='') or with only optional params like count/country; an agent invoking the tool with a differently-named parameter (e.g. search_term) that none of the three fallbacks match.

Common situations: LLM agents renaming the query parameter between calls, empty-string queries produced by templated prompts, migration from another search tool whose parameter is named search_query but the value evaluates falsy.

Related errors


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