jackwener/OpenCLI · error · CommandExecutionError
Xiaohongshu search failed: ${err?.message ?? String(err)}
Error message
Xiaohongshu search failed: ${err?.message ?? String(err)} What it means
A catch-all wrapper at the end of the xiaohongshu search command: any unexpected error that is not already a CliError is rethrown as a CommandExecutionError prefixed with 'Xiaohongshu search failed:'. It preserves the original message but loses the original stack/type, so you must read the embedded message to diagnose.
Source
Thrown at clis/xiaohongshu/search.js:917
}
}
const rows = harvest.rows
.filter((item) => item.title)
.slice(0, limit);
if (rows.length === 0) {
throw new EmptyResultError('xiaohongshu search', 'No usable notes were rendered for this query.');
}
return rows
.map((item, i) => ({
rank: i + 1,
...item,
published_at: noteIdToDate(item.url),
}));
}
catch (err) {
if (err instanceof CliError)
throw err;
throw new CommandExecutionError(`Xiaohongshu search failed: ${err?.message ?? String(err)}`);
}
},
});
export const __test__ = {
harvestOptionsForLimit,
stripXhsAuthorDateSuffix,
};
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the embedded message after the prefix — it is the original error's message — and fix that root cause.
- Verify network connectivity and that the search URL loads in the logged-in browser.
- Increase navigation/operation timeouts if the embedded message indicates a timeout.
- Catch this in your caller and retry with backoff for transient navigation failures.
- If the embedded message is an opaque TypeError, update the library — it may be a selector/contract change on the site.
Example fix
// before
const rows = await xhsSearch(query);
// after
try {
const rows = await xhsSearch(query);
} catch (err) {
const cause = String(err.message).replace('Xiaohongshu search failed: ', '');
if (/timeout|net::/i.test(cause)) return await retryWithBackoff(() => xhsSearch(query));
throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!browser.isConnected()) throw new Error('browser must be connected before running xiaohongshu search'); Type guard
function isCliError(e) { return e instanceof CliError; } Try / catch
try {
return await xhsSearch(query);
} catch (err) {
if (isCliError(err)) throw err;
const cause = err.message.replace(/^Xiaohongshu search failed: /, '');
if (/timeout|net::ERR/i.test(cause)) return retryWithBackoff(() => xhsSearch(query));
throw err;
} Prevention
- Ensure stable network and reachable XHS before running
- Set generous timeouts for navigation
- Distinguish CliError subclasses from this wrapper when handling
- Log the full embedded cause message
When it happens
Trigger: Any non-CliError exception escapes the try block in the command handler — e.g. navigation failures from page.goto, evaluate timeouts inside collectSearchHarvest, noteIdToDate input errors, or other runtime errors during harvest/processing.
Common situations: Navigation timeout because the search page never loaded; browser disconnected mid-harvest; page.evaluate returning undefined and downstream code throwing a TypeError; network outage during the search.
Related errors
- Failed to replace collapsed Xiaohongshu search tab: ${error?
- ${label} failed: ${error?.message ?? error}
- Failed to extract AIbase daily news: ${getErrorMessage(error
- 获取视频信息失败: ${err?.message || err}
- Failed to upload image to ChatGPT: ${err instanceof Error ?
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fa68581bc06f2c15.
Report an issue: GitHub.