microsoft/semantic-kernel · error · ServiceInvalidRequestError

count value must be less than or equal to 10.

Error message

count value must be less than or equal to 10.

What it means

_validate_options enforces options.top <= 10 because the Google Custom Search API num parameter accepts at most 10 results per request. Anything larger raises ServiceInvalidRequestError before the HTTP call is made.

Source

Thrown at python/semantic_kernel/connectors/google_search.py:283

        headers = {"user_agent": SEMANTIC_KERNEL_USER_AGENT}
        try:
            async with AsyncClient(timeout=5) as client:
                response = await client.get(full_url, headers=headers)
                response.raise_for_status()
                return GoogleSearchResponse.model_validate_json(response.text)
        except HTTPStatusError as ex:
            logger.error(f"Failed to get search results: {ex}")
            raise ServiceInvalidRequestError("Failed to get search results.") from ex
        except RequestError as ex:
            logger.error(f"Client error occurred: {ex}")
            raise ServiceInvalidRequestError("A client error occurred while getting search results.") from ex
        except Exception as ex:
            logger.error(f"An unexpected error occurred: {ex}")
            raise ServiceInvalidRequestError("An unexpected error occurred while getting search results.") from ex

    def _validate_options(self, options: SearchOptions) -> None:
        if options.top > 10:
            raise ServiceInvalidRequestError("count value must be less than or equal to 10.")

    def _parse_filter_lambda(self, filter_lambda: Callable | str) -> list[dict[str, str]]:
        """Parse a string lambda or string expression into a list of {field: value} dicts using AST."""
        expr = filter_lambda if isinstance(filter_lambda, str) else getsource(filter_lambda).strip()
        tree = ast.parse(expr, mode="eval")
        node = tree.body
        visitor = SearchLambdaVisitor(valid_parameters=QUERY_PARAMETERS)
        visitor.visit(node)
        return visitor.filters

    def _build_query(self, query: str, options: SearchOptions) -> str:
        params = {
            "key": self.settings.api_key.get_secret_value(),
            "cx": self.settings.engine_id,
            "num": options.top,
            "start": options.skip,
        }
        # parse the filter lambdas to query parameters

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Set top to 10 or less per call.
  2. For more results, paginate using skip (mapped to the API start param) in steps of <= 10.
  3. Clamp user-supplied counts before calling search.

Example fix

# before
results = await google.search('skates', top=25)  # -> [1306]

# after
top = min(requested_top, 10)
all_items = []
for skip in range(0, requested_top, top):
    res = await google.search('skates', top=top, skip=skip, include_total_count=True)
    all_items.extend(res.results)
Defensive patterns

Strategy: validation

Validate before calling

def safe_top(requested: int) -> int:
    if requested < 1:
        raise ValueError('top must be >= 1')
    return min(requested, 10)  # Google Custom Search max is 10

Try / catch

from semantic_kernel.exceptions import ServiceInvalidRequestError
try:
    results = await google.search(query, top=top)
except ServiceInvalidRequestError as ex:
    if 'less than or equal to 10' in str(ex):
        results = await google.search(query, top=10)
    else:
        raise

Prevention

When it happens

Trigger: Calling search(query, top=11) or any value greater than 10; passing SearchOptions(top=25); paging logic that computes a window larger than 10.

Common situations: Porting defaults from connectors that allow larger pages (e.g. Bing); UI defaulting to 20/50 results; bulk-export scripts requesting many results per call.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/03d17d2b5f896c6a. Report an issue: GitHub.