jackwener/OpenCLI · error · CommandExecutionError

Trip.com hotel detail page did not expose SSR hotel data (st

Error message

Trip.com hotel detail page did not expose SSR hotel data (state=${String(waitResult)})

What it means

This CommandExecutionError fires when the hotel detail page loaded but WAIT_FOR_HOTEL_DETAIL_JS returned a state other than 'content' or 'captcha' — the page never exposed Trip.com's SSR hotel data blob. It signals a page-structure or load problem rather than an auth problem.

Source

Thrown at clis/trip/hotel.js:43

        { name: 'id', required: true, positional: true, help: 'Numeric Trip.com hotel id (discover via the hotels list; e.g. 715233)' },
    ],
    columns: [
        'hotelId', 'name', 'enName',
        'star', 'score', 'scoreLabel', 'reviewCount', 'ratingBreakdown',
        'facilities', 'checkInOut',
        'cityName', 'address', 'lat', 'lon',
        'url',
    ],
    func: async (page, kwargs) => {
        const hotelId = parseHotelId('id', kwargs.id);
        const url = buildHotelDetailUrl(hotelId);
        await page.goto(url);
        const waitResult = await page.evaluate(WAIT_FOR_HOTEL_DETAIL_JS);
        if (waitResult === 'captcha') {
            throw new AuthRequiredError('trip.com', 'Trip.com is asking for a verification; complete it in your browser session and retry');
        }
        if (waitResult !== 'content') {
            throw new CommandExecutionError(`Trip.com hotel detail page did not expose SSR hotel data (state=${String(waitResult)})`);
        }
        const detail = await page.evaluate(buildHotelDetailExtractJs());
        if (!detail || typeof detail !== 'object') {
            throw new CommandExecutionError('Trip.com hotel detail SSR extraction returned malformed data');
        }
        if (!detail.hotelId || !detail.name) {
            throw new EmptyResultError('trip hotel', `No detail exposed for hotel id ${hotelId}`);
        }
        return [{ ...detail, url }];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the request — transient slow loads often resolve on a second attempt
  2. Verify the hotelId is valid by checking the hotel URL opens with data in a real browser
  3. Update the library / WAIT_FOR_HOTEL_DETAIL_JS selectors if Trip.com changed its SSR markup
  4. Increase page wait/timeout budget for slow networks

Example fix

// before
await tripHotelDetail({ id: '123456' }); // intermittent state=timeout
// after
await withRetry(() => tripHotelDetail({ id: '123456' }), { attempts: 3, backoffMs: 1000 });
Defensive patterns

Strategy: retry

Validate before calling

const url = buildHotelDetailUrl(hotelId);
if (!Number.isFinite(Number(hotelId)) || Number(hotelId) <= 0) {
  throw new Error(`invalid hotel id: ${hotelId}`);
}

Try / catch

try {
  return await tripHotelDetail({ id });
} catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('SSR hotel data')) {
    await sleep(1500);
    return await tripHotelDetail({ id }); // one retry for transient slow loads
  }
  throw e;
}

Prevention

When it happens

Trigger: The detail page rendered a slow/error/redirect state so the SSR data node never appeared within the wait script's tolerance: slow network, changed Trip.com markup, or a soft error page for an invalid hotelId.

Common situations: Trip.com front-end update renaming the SSR data variable, timeouts on slow connections, deleted/unavailable hotel ids redirecting to a generic page, or intermittent CDN errors.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9b9a638f024525b7. Report an issue: GitHub.