infiniflow/ragflow · error · RuntimeError

SerpApi returned no organic_results.

Error message

SerpApi returned no organic_results.

What it means

Raised as RuntimeError by the Google (SerpApi) search tool when the SerpApi response dict lacks 'organic_results'. SerpApi signals an invalid API key, exhausted quota, or an empty result set through an 'error' field while omitting 'organic_results'; the tool surfaces that error message, and only falls back to the literal 'SerpApi returned no organic_results.' when neither key exists.

Source

Thrown at agent/tools/google.py:505

            return ""

        params = {"api_key": self._param.api_key, "engine": "google", "q": kwargs["q"], "google_domain": "google.com", "gl": self._param.country, "hl": self._param.language}
        last_e = ""
        for _ in range(self._param.max_retries + 1):
            if self.check_if_canceled("Google processing"):
                return

            try:
                search = GoogleSearch(params).get_dict()

                if self.check_if_canceled("Google processing"):
                    return

                # serpapi reports an invalid key, exhausted quota or an empty result
                # set through an "error" field and omits "organic_results"; surface that
                # message instead of raising a cryptic KeyError on the missing key.
                if "organic_results" not in search:
                    raise RuntimeError(search.get("error", "SerpApi returned no organic_results."))

                organic_results = search["organic_results"]
                # a result may omit any of these; note the fallback of the "description"
                # lookup is evaluated eagerly, so it has to be a .get() too or a result
                # carrying a description but no snippet raises KeyError.
                self._retrieve_chunks(
                    organic_results,
                    get_title=lambda r: r.get("title", ""),
                    get_url=lambda r: r.get("link", ""),
                    get_content=lambda r: r.get("about_this_result", {}).get("source", {}).get("description", r.get("snippet", "")),
                )
                self.set_output("json", organic_results)
                return self.output("formalized_content")
            except Exception as e:
                if self.check_if_canceled("Google processing"):
                    return

                last_e = e

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Read the RuntimeError text — 'Invalid API key' or 'Your searches are exhausted' tells you to fix the key or upgrade/top-up the plan at serpapi.com.
  2. Verify the key with a curl 'https://serpapi.com/search?q=test&api_key=KEY' and confirm the response contains organic_results.
  3. If the key is valid and quota remains, loosen the query (remove restrictive site:/filetype: filters, check gl/hl params) so organic results exist.
  4. Cache search responses to avoid burning quota on repeated agent runs.
Defensive patterns

Strategy: fallback

Validate before calling

def serpapi_key_ok(key: str) -> bool:
    import requests
    r = requests.get("https://serpapi.com/account", params={"api_key": key}, timeout=10)
    return r.ok and r.json().get("account_rate_limit_per_hour", 0) >= 0

Try / catch

try:
    return google_tool._invoke(query=q)
except RuntimeError as e:
    if "organic_results" in str(e):
        return ""  # zero results: benign
    log.error("serpapi: %s", e)  # quota/key problem
    return fallback_search(q)

Prevention

When it happens

Trigger: GoogleSearch(params).get_dict() with an invalid/expired SERPAPI_API_KEY ('Your account is suspended' / 'Invalid API key'), a plan whose searches/month quota is exhausted, or a legitimate query that simply yields zero organic results (obscure query, num=0, heavy site: filtering).

Common situations: Agent canvas Google-search nodes after the SerpApi free trial (100 searches) runs out, rotated keys not updated in the component parameters, geo/gl parameters producing empty result pages, or a typo'd key configured per-node instead of globally.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/0f51253f8ac2ca1f. Report an issue: GitHub.