assafelovic/gpt-researcher · error · Exception

No results found with Tavily API search.

Error message

No results found with Tavily API search.

What it means

After calling the Tavily search API, the retriever validates the shape of the response: Tavily is expected to return a JSON object (dict) with a top-level 'results' key. If the response is not a dict (e.g., a list or scalar JSON body, often due to API or proxy glitches), the code raises 'No results found with Tavily API search.' despite the HTTP call technically succeeding.

Source

Thrown at gpt_researcher/retrievers/tavily/tavily_search.py:138

            site_domains = _SITE_OPERATOR_PATTERN.findall(query)
            if site_domains:
                query = _SITE_OPERATOR_PATTERN.sub("", query).strip()
                # Keep only the domain part (Tavily matches domains, not paths)
                site_domains = [d.strip(",").split("/")[0] for d in site_domains]
                include_domains = list(dict.fromkeys(site_domains + (include_domains or [])))

            # Search the query (Tavily rejects queries longer than 400 chars)
            results = self._search(
                query[:400],
                search_depth="basic",
                max_results=max_results,
                topic=self.topic,
                include_domains=include_domains,
            )
            # API/proxy glitches can yield a list or scalar JSON body; only dict
            # responses have a top-level "results" key we understand.
            if not isinstance(results, dict):
                raise Exception("No results found with Tavily API search.")
            sources = results.get("results", [])
            if not isinstance(sources, list) or not sources:
                raise Exception("No results found with Tavily API search.")
            # Return the results. Guard each source against missing/None
            # fields so a single malformed hit does not drop the whole page.
            search_response = []
            for obj in sources:
                if not isinstance(obj, dict):
                    continue
                href = obj.get("url")
                if not href:
                    continue
                body = obj.get("content") or obj.get("snippet") or ""
                search_response.append({"href": href, "body": body})
        except Exception as e:
            print(f"Error: {e}. Failed fetching sources. Resulting in empty response.")
            search_response = []
        return search_response

View on GitHub (pinned to 6f998577d5)

Solutions

  1. Retry the search — transient API/proxy glitches often resolve themselves.
  2. Pin/upgrade the tavily-python package to a version whose response format matches this retriever's expectations (pip install -U tavily-python).
  3. If behind a proxy, bypass it for api.tavily.com or fix the proxy's response rewriting.
  4. Inspect the raw response by calling tavily_client.search(...) directly to see what body is actually returned.
  5. Fall back to a different retriever (e.g., 'duckduckgo' or 'tavily'-alternative) if Tavily consistently returns malformed bodies.

Example fix

# before
results = tavily_client.search(query)  # proxy returns [ ... ] (a list)
retriever.search()  # raises: No results found with Tavily API search.

# after
results = tavily_client.search(query)
if not isinstance(results, dict):
    results = {'results': results if isinstance(results, list) else []}  # normalize, then handle empty gracefully
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight: call Tavily directly and confirm the response shape
resp = tavily_client.search(query)
assert isinstance(resp, dict) and isinstance(resp.get('results'), list), 'unexpected Tavily response shape'

Type guard

def is_tavily_response(v) -> bool:
    return isinstance(v, dict) and isinstance(v.get('results'), list)

Try / catch

for attempt in range(3):
    try:
        return retriever.search()
    except Exception as e:
        if 'No results found' in str(e) and attempt < 2:
            time.sleep(2 ** attempt)
            continue
        raise

Prevention

When it happens

Trigger: Calling tavily_search's search() when the Tavily client returns a non-dict payload — for example a proxy returning a JSON array/scalar, an API format change, or a degraded response. The isinstance(results, dict) check fails and the generic 'no results' Exception is thrown.

Common situations: Corporate proxies or API gateways rewriting/mangling the response body; Tavily changing its response schema between SDK versions; empty or error payloads returned as lists; intermittent API glitches that are transient and succeed on retry.

Related errors


AI-assisted analysis of assafelovic/gpt-researcher@6f998577d5 (2026-08-28). Data as JSON: /api/errors/2ca810bdf13d726b. Report an issue: GitHub.