ScrapeGraphAI/Scrapegraph-ai · error · ValueError

Search engine must be one of: {', '.join(valid_engines)}

Error message

Search engine must be one of: {', '.join(valid_engines)}

What it means

ValueError from the pydantic validator on search_engine in scrapegraphai.utils.research_web: the configured search engine must be one of duckduckgo, bing, searxng, serper (case-insensitive; value is lowercased before comparison).

Source

Thrown at scrapegraphai/utils/research_web.py:67

    query: str = Field(..., description="Search query")
    search_engine: str = Field("duckduckgo", description="Search engine to use")
    max_results: int = Field(10, description="Maximum number of results to return")
    port: Optional[int] = Field(8080, description="Port for SearXNG")
    timeout: int = Field(10, description="Request timeout in seconds")
    proxy: Optional[Union[str, Dict, ProxyConfig]] = Field(
        None, description="Proxy configuration"
    )
    serper_api_key: Optional[str] = Field(None, description="API key for Serper")
    region: Optional[str] = Field(None, description="Country/region code")
    language: str = Field("en", description="Language code")

    @validator("search_engine")
    def validate_search_engine(cls, v):
        """Validate search engine."""
        valid_engines = {"duckduckgo", "bing", "searxng", "serper"}
        if v.lower() not in valid_engines:
            raise ValueError(
                f"Search engine must be one of: {', '.join(valid_engines)}"
            )
        return v.lower()

    @validator("query")
    def validate_query(cls, v):
        """Validate search query."""
        if not v or not isinstance(v, str):
            raise ValueError("Query must be a non-empty string")
        return v

    @validator("max_results")
    def validate_max_results(cls, v):
        """Validate max results."""
        if v < 1 or v > 100:
            raise ValueError("max_results must be between 1 and 100")
        return v

View on GitHub (pinned to 532dfffbf6)

Solutions

  1. Use one of: duckduckgo, bing, searxng, serper
  2. For Google-style results use 'serper' with a SERPER_API_KEY
  3. Check spelling/case (case-insensitive but must match exactly otherwise)

Example fix

# before
params = {"search_engine": "google", "query": "..."}
# after
params = {"search_engine": "serper", "query": "..."}  # + set SERPER_API_KEY
Defensive patterns

Strategy: validation

Validate before calling

VALID = {"duckduckgo", "bing", "searxng", "serper"}
search_engine = search_engine.lower()
assert search_engine in VALID, f"pick one of {sorted(VALID)}"

Type guard

def is_supported_search_engine(name: str) -> bool:
    return isinstance(name, str) and name.lower() in {"duckduckgo", "bing", "searxng", "serper"}

Try / catch

try:
    params = SearchParams(query=q, search_engine=engine)
except ValidationError as e:
    engine = "duckduckgo"
    params = SearchParams(query=q, search_engine=engine)

Prevention

When it happens

Trigger: Setting search_engine to 'google', 'google_serp', or any string outside the four allowed values on the research/search web model.

Common situations: Upgrading from versions supporting more engines; copying configs expecting Google search; typos like 'serper.dev'.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of ScrapeGraphAI/Scrapegraph-ai@532dfffbf6 (2026-08-28). Data as JSON: /api/errors/2f55d4f1aeb15b00. Report an issue: GitHub.