jackwener/OpenCLI · error · CommandExecutionError
Trip.com poiSearch returned invalid JSON: ${err instanceof E
Error message
Trip.com poiSearch returned invalid JSON: ${err instanceof Error ? err.message : String(err)} What it means
fetchPoiSearch calls response.json() and re-throws any parse failure as CommandExecutionError with 'Trip.com poiSearch returned invalid JSON: ...'. This means the server responded with a non-JSON body (HTML error page, empty body, truncated response) despite a successful status code.
Source
Thrown at clis/trip/utils.js:851
headers: { 'content-type': 'application/json', currency: 'USD' },
body: JSON.stringify({
key: keyword,
mode: '0',
tripType: 'RT',
Head: { Currency: 'USD', Locale: 'en-US', Source: 'ONLINE', Channel: 'EnglishSite', ClientID: 'opencli-trip' },
}),
});
} catch (err) {
throw new CommandExecutionError(`Trip.com poiSearch fetch failed: ${err instanceof Error ? err.message : String(err)}`);
}
if (!response.ok) {
throw new CommandExecutionError(`Trip.com poiSearch failed with status ${response.status}`);
}
let payload;
try {
payload = await response.json();
} catch (err) {
throw new CommandExecutionError(`Trip.com poiSearch returned invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
}
if (!Array.isArray(payload?.results)) {
throw new CommandExecutionError('Trip.com poiSearch returned malformed payload: missing results array');
}
return payload.results;
}
/**
* Flatten POI results into a flat suggestion list: each top-level city keeps its
* own row, and its `childResults` (nearby airports) follow, so a single search
* surfaces both the city id and the airport codes.
*/
export function flattenPoiResults(results) {
const rows = [];
for (const result of results) {
if (!result || typeof result !== 'object') continue;
rows.push(result);
if (Array.isArray(result.childResults)) {View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw response body (curl the endpoint) to see what was actually returned
- Handle anti-bot challenges: the HTML body usually indicates Trip.com wants verification or different headers
- Retry — truncated responses are often transient
- Add a proxy/debug layer (mitm, request logging) to capture the exact body and headers
Example fix
// before
const results = await fetchPoiSearch(...) // got HTML instead of JSON
// after
try { const r = await fetchPoiSearch(...) } catch (e) {
if (String(e.message).includes('invalid JSON')) { console.error('non-JSON body — check for anti-bot page'); }
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
const looksLikeJson = (s) => typeof s === 'string' && s.trimStart().startsWith('{'); Try / catch
try {
const results = await searchAttractions(keyword);
} catch (e) {
if (/poiSearch returned invalid JSON/.test(e.message)) {
console.error('Non-JSON body received — likely anti-bot page or proxy HTML. Inspect with curl.');
return retryAfterDelay(() => searchAttractions(keyword), 5000);
}
throw e;
} Prevention
- Curl the endpoint to know what a healthy body looks like
- Detect anti-bot HTML challenges and rotate headers/cookies/IPs
- Retry truncated responses — they are often transient
- Route through a debug proxy when diagnosing recurring body issues
When it happens
Trigger: Trip.com returns an HTML challenge/login page with 200 status; response body truncated mid-stream; empty body on 204; CDN serving a cached HTML error page; charset/BOM issues in the body.
Common situations: Anti-bot interstitials returned with 200; proxy servers injecting their own HTML error pages; flaky mobile connections truncating responses; API returning plain-text rate-limit notices.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- coingecko global returned malformed JSON: ${err?.message ??
- Trip.com package search returned invalid JSON: ${err instanc
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- coingecko derivatives returned malformed JSON: ${err?.messag
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/286a348936b2a48b.
Report an issue: GitHub.