jackwener/OpenCLI · info · EmptyResultError
No ${kwargs.type || 'private'} tours for "${query}"
Error message
No ${kwargs.type || 'private'} tours for "${query}" What it means
This EmptyResultError means the tour search page explicitly reported 'no routes found' for the query (result.status === 'empty'), i.e. Trip.com has no matching tours for that destination and tour type. It is a clean no-match signal, deliberately separated from schema-drift and captcha cases.
Source
Thrown at clis/trip/tour.js:62
'price', 'currency',
'url',
],
func: async (page, kwargs) => {
const query = parseKeyword('query', kwargs.query);
const tourType = parseTourType(kwargs.type);
const limit = parseListLimit(kwargs.limit);
const searchUrl = buildTourSearchUrl(query, tourType);
await page.goto(searchUrl);
const result = await page.evaluate(buildTourSearchJs(query));
if (!result || typeof result !== 'object') {
throw new CommandExecutionError('Trip.com tour search returned malformed data');
}
if (result.status === 'captcha') {
throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');
}
if (result.status === 'empty') {
throw new EmptyResultError('trip tour', `No ${kwargs.type || 'private'} tours for "${query}"`);
}
if (result.status !== 'content') {
throw new CommandExecutionError(`Trip.com tour search did not return results (state=${String(result.status)})`);
}
// Products captured but none carry a name is drift (schema moved), not an empty search;
// a genuine no-match resolves as status 'empty' above off the page's "0 routes found".
const rows = Array.isArray(result.rows) ? result.rows.filter((r) => r.name) : [];
if (rows.length === 0) {
throw new CommandExecutionError('Trip.com tour search captured products but none carried a name (the product markup may have changed)');
}
return rows.slice(0, limit).map((r, i) => ({
rank: i + 1,
name: r.name,
type: r.type,
rating: r.rating,
reviews: r.reviews,
price: r.price,
currency: 'USD',View on GitHub (pinned to 49907e53dc)
Solutions
- Try the other --type value (group vs private) — availability differs per tab.
- Simplify or correct the destination query string.
- Search a nearby major city that has tour inventory.
- Catch EmptyResultError and treat it as an empty result set in your application.
Example fix
// before
await tripTour({ query: 'Hallstatt', type: 'group' }); // no group tours
// after
try {
return await tripTour({ query: 'Hallstatt', type: 'private' });
} catch (e) {
if (e.name === 'EmptyResultError') return [];
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check the query before spending a page load
if (!query || query.trim().length < 3) throw new Error('provide a meaningful destination name'); Type guard
function isPlausibleDestination(q) { return typeof q === 'string' && q.trim().length >= 3; } Try / catch
try {
const rows = await tourSearch(query, type);
} catch (e) {
if (e instanceof EmptyResultError) return [];
throw e;
} Prevention
- Verify the destination exists on trip.com (via POI search) before tour search.
- Try both tour types when a market may lack one.
- Catch EmptyResultError and return an empty list instead of failing the workflow.
- Keep a list of destinations known to have zero tour inventory.
When it happens
Trigger: Calling tour search with a destination that has zero private (or group, per --type) tours on Trip.com, or a misspelled/obscure query that matches no tour products.
Common situations: Small towns or attractions Trip.com doesn't sell tours for; using --type=group in a market where only private tours exist; localized transliterations that match nothing.
Related errors
- No attractions for "${query}"
- Trip.com attraction cards rendered but parser did not find r
- No car rentals for city id ${cityId}
- No round-trip flights for ${fromCode} to ${toCode} on ${depa
- No flights for ${fromCode} to ${toCode} on ${date}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/0d7316d3a997344e.
Report an issue: GitHub.