jackwener/OpenCLI · error · ArgumentError

hotel id must be a positive integer, got ${JSON.stringify(ra

Error message

hotel id must be a positive integer, got ${JSON.stringify(raw)}

What it means

After the presence check, parseHotelId delegates to parseStrictPositiveInteger('id', raw); any failure (non-numeric text, decimals, zero, negatives, junk-suffixed numbers) is rethrown as ArgumentError 'hotel id must be a positive integer'. The ID is interpolated directly into the hotel detail URL, so it must be a clean positive integer.

Source

Thrown at clis/ctrip/utils.js:608

      const result = detect();
      if (result) { observer.disconnect(); resolve(result); }
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
    setTimeout(() => { observer.disconnect(); resolve('timeout'); }, 10000);
  })
`;

/* ------------------------- hotel detail (browser SSR) ------------------------- */

/** Validate a numeric Ctrip hotel id (returned by `ctrip hotel-suggest`). */
export function parseHotelId(raw) {
    if (raw === undefined || raw === null || String(raw).trim() === '') {
        throw new ArgumentError('hotel id is required (numeric id from `ctrip hotel-suggest`, e.g. 375539)');
    }
    try {
        return parseStrictPositiveInteger('id', raw);
    } catch {
        throw new ArgumentError(`hotel id must be a positive integer, got ${JSON.stringify(raw)}`);
    }
}

export function buildHotelDetailUrl(hotelId) {
    return `https://hotels.ctrip.com/hotels/detail/?hotelid=${hotelId}`;
}

/**
 * Browser-context IIFE that projects the single-hotel profile from
 * `__NEXT_DATA__.props.pageProps.hotelDetailResponse`. Rating sub-scores, hot
 * facilities, and the check-in/out policy are each joined into one string so the
 * profile stays a single flat row. Returns `null` when the SSR block is absent,
 * so the caller raises a typed error instead of surfacing blanks. Room-level
 * nightly prices load via a post-SSR XHR into hashed CSS-module cards and are out
 * of scope here, the same way `flight`'s post-load price XHR is.
 */
export function buildHotelDetailExtractJs() {
    return `

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run `ctrip hotel-suggest` and copy the exact numeric hotel id.
  2. Strip non-digit characters and trim whitespace before passing the value.
  3. Use a strictly positive integer (>= 1); decimals, zero and negatives are rejected.

Example fix

// before
ctrip hotel-detail --id "hotelid=375539"
// after
ctrip hotel-detail --id 375539
Defensive patterns

Strategy: validation

Validate before calling

const n = Number(String(raw).trim());
if (!Number.isInteger(n) || n < 1) throw new Error('hotel id must be a positive integer, got ' + raw);

Type guard

const isPositiveInt = (v) => typeof v === 'number' ? Number.isInteger(v) && v > 0 : /^\d+$/.test(String(v).trim());

Try / catch

try {
  const id = parseHotelId(raw);
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('positive integer')) {
    const digits = String(raw).replace(/\D/g, '');
    if (digits) return parseHotelId(digits);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a hotel id like 'abc', '375539.5', '0', '-1', 'id:375539', or a value with trailing spaces/invisible characters to the hotel-detail command.

Common situations: Pasting IDs with formatting from HTML/URLs (e.g. 'hotelid=375539&'), mixing up city IDs with hotel IDs, or hand-typing IDs with typos.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


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