# Debug search responses

When an agent gives an unexpected result, call the same tool as a plain Python function first. This separates SerpApi request problems from model and SDK behavior.


# Inspect a request and response

``` python
import json

from serpapi_search_tools import SearchResultFormat, SearchResultMode, web_search

search = web_search(
    provider="function",
    allowed_engines=["google_light"],
    default_params={"hl": "en", "gl": "us"},
    result_limit=None,
    mode=SearchResultMode.FULL,
    response_format=SearchResultFormat.JSON,
)
response = json.loads(search(query="Python packaging tutorials"))

print(response.get("search_parameters"))
for result in response.get("organic_results", []):
    print(result.get("title"), result.get("link"))
```

Plain callables and SDK tools use the same search logic. If the direct call succeeds, inspect the arguments produced by the agent next.


# Know the result section

Compact mode returns these common result sections:

| Tool | Common result section |
|----|----|
| [web_search](../reference/web_search.md#serpapi_search_tools.web_search) | `organic_results` |
| [news_search](../reference/news_search.md#serpapi_search_tools.news_search) | `news_results` |
| [maps_search](../reference/maps_search.md#serpapi_search_tools.maps_search) | `local_results` or `place_results` for an exact place |
| [images_search](../reference/images_search.md#serpapi_search_tools.images_search) | `images_results` |
| [shopping_search](../reference/shopping_search.md#serpapi_search_tools.shopping_search) | `shopping_results` or engine-specific product results |
| [videos_search](../reference/videos_search.md#serpapi_search_tools.videos_search) | `video_results`, `shorts_results`, `channel_results`, `playlist_results`, `movie_results`, or `category_results` |
| [hotels_search](../reference/hotels_search.md#serpapi_search_tools.hotels_search) | `properties` |
| [flights_search](../reference/flights_search.md#serpapi_search_tools.flights_search) | `best_flights`, `other_flights` |
| [travel_explore_search](../reference/travel_explore_search.md#serpapi_search_tools.travel_explore_search) | `destinations` |

Print `response.keys()` and `response.get("error")` when the expected section is absent. To inspect `search_metadata` and `search_parameters`, create the debug callable with `mode=SearchResultMode.FULL` as shown above.


# Inspect travel request construction

Travel tools do not accept a free-text `q` substitute. Their structured fields are sent directly to SerpApi:

``` python
from serpapi_search_tools import flights_search

search = flights_search(provider="function")
raw = search(
    departure_id="LAX",
    arrival_id="AUS",
    outbound_date="2030-08-01",
    return_date="2030-08-05",
    adults=2,
)
```

The package infers SerpApi's trip `type` from the presence of `return_date` and maps semantic cabin names such as `business` to the numeric API value.


# Common failures

- **No SerpApi key:** set `SERPAPI_API_KEY`, pass `api_key=`, or verify your secret manager returned a non-empty value.
- **Wrong constructor:** use [news_search](../reference/news_search.md#serpapi_search_tools.news_search), [maps_search](../reference/maps_search.md#serpapi_search_tools.maps_search), or another dedicated tool instead of passing a vertical engine to [web_search](../reference/web_search.md#serpapi_search_tools.web_search).
- **Invalid travel dates:** use `YYYY-MM-DD`; checkout must follow check-in and a return date cannot precede departure.
- **Invalid flight location:** use a specific airport IATA code or a city KGMID beginning with `/m/` or `/g/`; metropolitan codes such as `LON` and `PAR` are not airport IDs.
- **Invalid child data:** `hotels_search.children_ages` must contain exactly one age from 1 through 17 for each child; use `1` for a child under one year old.
- **Incompatible defaults:** remove mutually exclusive engine parameters named by the validation error.
- **Direct call works but the agent fails:** compare the SDK's tool name and the arguments emitted by the agent with the fields documented for that tool.
- **Direct call also fails:** keep the model out of the test until the SerpApi request and response are correct.


# Catch provider and transport failures

Invalid local inputs raise `ValueError` before a SerpApi request. Failures returned by the built-in SerpApi client raise [SerpApiSearchError](../reference/SerpApiSearchError.md#serpapi_search_tools.SerpApiSearchError):

``` python
from serpapi_search_tools import SerpApiSearchError, web_search

search = web_search(provider="function")
try:
    encoded = search(query="Python packaging")
except ValueError as exc:
    print(f"Fix the tool arguments: {exc}")
except SerpApiSearchError as exc:
    print(f"SerpApi could not complete the request: {exc}")
```

The error message replaces any API key found in the upstream request URL with `[REDACTED]`, making it safer to retain ordinary application and CI logs.

Return to [Usage and composition](usage.md) after the direct call works, or open the complete example under [Choose an agent SDK](frameworks.md).
