crewAIInc/crewAI · error · ValueError
search_query is required
Error message
search_query is required
What it means
SerperDevTool._run raises ValueError("search_query is required") when neither the search_query nor the query keyword argument is truthy. The tool checks kwargs.get("search_query") or kwargs.get("query") and, combined with there being no instance-level default query, an empty/missing query aborts before any request.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/serper_dev_tool/serper_dev_tool.py:324
if "relatedSearches" in results:
formatted_results["relatedSearches"] = self._process_related_searches(
results["relatedSearches"]
)
elif search_type == "news":
if "news" in results:
formatted_results["news"] = self._process_news_results(results["news"])
return formatted_results
def _run(self, **kwargs: Any) -> FormattedResults:
"""Execute the search operation."""
search_query: str | None = kwargs.get("search_query") or kwargs.get("query")
search_type: str = kwargs.get("search_type", self.search_type)
save_file = kwargs.get("save_file", self.save_file)
if not search_query:
raise ValueError("search_query is required")
results = self._make_api_request(search_query, search_type)
formatted_results = {
"searchParameters": {
"q": search_query,
"type": search_type,
**results.get("searchParameters", {}),
}
}
formatted_results.update(self._process_search_results(results, search_type))
formatted_results["credits"] = results.get("credits", 1)
if save_file:
_save_results_to_file(json.dumps(formatted_results, indent=2))
return formatted_results # type: ignore[return-value]View on GitHub (pinned to 754d7323be)
Solutions
- Pass a non-empty search string: tool._run(search_query="crewai") (query= is also accepted).
- If an agent is producing empty queries, add a description/example to the tool input schema or validate the model output before invoking the tool.
- Wrap the call in try/except ValueError to degrade gracefully (return a prompt asking for a query).
Example fix
# before result = serper_tool._run() # after result = serper_tool._run(search_query="latest crewai release")
Defensive patterns
Strategy: validation
Validate before calling
query = (kwargs.get("search_query") or kwargs.get("query") or "").strip()
if not query:
raise ValueError("A non-empty search_query must be provided")
result = serper_tool._run(search_query=query) Type guard
def has_search_query(kwargs: dict) -> bool:
return bool((kwargs.get("search_query") or kwargs.get("query") or "").strip()) Try / catch
try:
result = serper_tool._run(**kwargs)
except ValueError as e:
if "search_query is required" in str(e):
return "Please provide a search query." # agent re-ask
raise Prevention
- Validate that the query is a non-empty string before invoking the tool.
- When agents call the tool, make search_query a required schema field and reject empty model outputs.
When it happens
Trigger: Calling tool._run() with no arguments; calling _run(search_query="") or _run(query=None); or an LLM agent producing a tool call that omits the query string.
Common situations: Agent frameworks generating malformed tool arguments (empty string query from the model), or test code invoking the tool without inputs. Very common when the tool schema is bypassed and _run is called directly.
Related errors
- Website URL must be provided either during initialization or
- URL scheme '{parsed.scheme}' is not allowed. Only http and h
- URL has no hostname: '{url}'
- Query cannot be empty
- action={self.action!r} requires 'path'.
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/31ff432b86d4c0e2.
Report an issue: GitHub.