koala73/worldmonitor · warning · Error

no results

Error message

no results

What it means

Thrown inside the searchGoogleDates cache producer when the relay answered 2xx but the JSON body has no dates array — either the body carried an error field (json.error is re-thrown as the message) or the shape was unexpected ('no results' is the fallback message). The outer catch turns it into the degraded response {dates: [], degraded: true, error: 'no results'}; the same string also appears on the cachedFetchJson null path without any throw.

Source

Thrown at server/worldmonitor/aviation/v1/search-google-dates.ts:64

  });
  for (const airline of airlines) {
    params.append('airlines', airline);
  }

  const cacheKey = `aviation:gf-dates:${origin}:${destination}:${startDate}:${endDate}:${params.toString()}:v1`;

  try {
    const data = await cachedFetchJson<{ dates: unknown[]; partial?: boolean }>(
      cacheKey,
      CACHE_TTL,
      async () => {
        const resp = await fetch(`${relayBaseUrl}/google-flights/search-dates?${params}`, {
          headers: getRelayHeaders(),
          signal: AbortSignal.timeout(30_000),
        });
        if (!resp.ok) throw new Error(`relay returned ${resp.status}`);
        const json = (await resp.json()) as { dates?: unknown[]; partial?: boolean; error?: string };
        if (!Array.isArray(json.dates)) throw new Error(json.error ?? 'no results');
        return { dates: json.dates, partial: json.partial };
      },
    );

    if (!data) {
      return { dates: [], degraded: true, error: 'no results' };
    }

    return {
      dates: data.dates as SearchGoogleDatesResponse['dates'],
      degraded: data.partial === true,
      error: data.partial === true ? 'partial results: one or more date chunks failed' : '',
    };
  } catch (err) {
    return { dates: [], degraded: true, error: err instanceof Error ? err.message : 'search failed' };
  }
}

View on GitHub (pinned to 9361220cc0)

Solutions

  1. Verify the request parameters (IATA codes, start/end dates within a servable range)
  2. Check the degraded flag and surface a retry-later message rather than 'no results found'
  3. If it persists for valid routes, inspect the relay scraper logs — a 200-with-error usually means the upstream scrape failed
  4. Retry later; anti-bot failures are often transient and nothing is cached on failure
Defensive patterns

Strategy: fallback

Validate before calling

// validate the route/date inputs before spending a relay round-trip
const IATA = /^[A-Z]{3}$/;
if (!IATA.test(origin) || !IATA.test(destination) || !/\d{4}-\d{2}-\d{2}/.test(startDate)) {
  return clientError('invalid origin/destination/dates');
}

Type guard

function isNoResultsDegraded(r: { degraded: boolean; error: string }): boolean {
  return r.degraded && r.error === 'no results';
}

Try / catch

const res = await searchGoogleDates(req);
if (isNoResultsDegraded(res)) {
  // ambiguous between 'truly empty' and 'relay scrape failed' — surface retry, not a definitive empty
}

Prevention

When it happens

Trigger: Relay returns 200 with {error: 'scrape failed'} after the Google Flights scraper got blocked; relay returns 200 with an unexpected body shape (dates missing or not an array); genuine empty route/date-range where the relay reports it via error instead of an empty array.

Common situations: Google Flights anti-bot countermeasures causing the relay's scraper to fail; requesting an invalid or unserved origin/destination/date combination; relay version returning a changed response schema.

Related errors


AI-assisted analysis of koala73/worldmonitor@9361220cc0 (2026-08-21). Data as JSON: /api/errors/e847596f12809731. Report an issue: GitHub.