jackwener/OpenCLI · error · CommandExecutionError
Zhihu collection request failed (HTTP ${status})
Error message
Zhihu collection request failed (HTTP ${status}) What it means
fetchCollectionPage throws CommandExecutionError when the collection API request failed with a non-401/403 HTTP status (the status is interpolated into the message) or with no usable response at all. It distinguishes transient/network failures from auth failures handled by 5130.
Source
Thrown at clis/zhihu/collection.js:37
return n;
}
async function fetchCollectionPage(page, collectionId, offset, limit) {
const url = `https://www.zhihu.com/api/v4/collections/${collectionId}/items?offset=${offset}&limit=${limit}`;
const data = await page.evaluate(`
(async () => {
const r = await fetch(${JSON.stringify(url)}, { credentials: 'include' });
if (!r.ok) return { __httpError: r.status };
return await r.json();
})()
`);
if (!data || data.__httpError) {
const status = data?.__httpError;
if (status === 401 || status === 403) {
throw new AuthRequiredError('www.zhihu.com', 'Failed to fetch collection data from Zhihu. Please ensure you are logged in.');
}
throw new CommandExecutionError(
status ? `Zhihu collection request failed (HTTP ${status})` : 'Zhihu collection request failed',
'Try again later or rerun with -v for more detail',
);
}
return data;
}
function itemKey(item) {
const content = item?.content || {};
return `${content.type || ''}:${content.id || content.url || JSON.stringify(content).slice(0, 80)}`;
}
function mapCollectionItem(item, rank) {
const content = item.content || {};
const type = content.type || '';
if (!['answer', 'article', 'pin'].includes(type)) {
throw new CommandExecutionError(
`Zhihu collection returned unsupported content type: ${type || 'missing'}`,View on GitHub (pinned to 49907e53dc)
Solutions
- Check the HTTP status in the message: 404 means the collection ID is wrong, 429 means slow down
- Retry after a delay, especially for 429 or 5xx statuses
- Verify the collection ID exists and is public
- Rerun with -v for detailed request/response logging
Example fix
// before opencli zhihu collection 8328329 // 404: wrong id // after opencli zhihu collection 83283292 // correct numeric id
Defensive patterns
Strategy: retry
Validate before calling
if (!/^\d+$/.test(String(id))) throw new Error('use a numeric zhihu collection id'); Type guard
function isRetryableHttpError(d) {
const s = d?.__httpError;
return typeof s === 'number' && s !== 401 && s !== 403 && (s === 429 || s >= 500 || s === 0);
} Try / catch
try {
return await zhihuCollection(id);
} catch (e) {
if (/HTTP (429|5\d\d)/.test(e.message)) { await sleep(backoff); return zhihuCollection(id); }
throw e;
} Prevention
- Back off and retry on 429/5xx instead of tight-looping
- Verify collection IDs exist and are public before scripting bulk fetches
- Handle null responses (network drops) with a bounded retry
- Use -v logging to capture status codes for diagnosis
When it happens
Trigger: page.evaluate fetch returns __httpError with a status other than 401/403 (e.g. 404 for a nonexistent collection, 429 rate limit, 5xx server error), or data is null/undefined (network failure, page navigation interrupted).
Common situations: Typo in the collection ID causing 404; Zhihu returning 429 after rapid repeated calls; transient network outage; Zhihu server-side 5xx during maintenance.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- ${errorLabel} from Zhihu failed (HTTP ${status})
- autohome ${contextHint} HTTP ${resp.status}
- Ctrip flight API returned HTTP ${status || 'unknown'}
- dongchedi ${contextHint} HTTP ${resp.status}
- eastmoney convertible failed: HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3d2577f83829fe0a.
Report an issue: GitHub.