jackwener/OpenCLI · error · Error
Unexpected response structure
Error message
Unexpected response structure
What it means
Same structural guard as creator-profile: thrown when the creator-stats evaluate result lacks a `data` property, so the CLI refuses to index into `data.data[period]`. It indicates the page returned something other than the expected `{ data: {...} }` envelope.
Source
Thrown at clis/xiaohongshu/creator-stats.js:52
await page.goto('https://creator.xiaohongshu.com/new/home');
const data = await page.evaluate(`
async () => {
try {
const resp = await fetch('/api/galaxy/creator/data/note_detail_new', {
credentials: 'include',
});
if (!resp.ok) return { error: 'HTTP ' + resp.status };
return await resp.json();
} catch (e) {
return { error: e.message };
}
}
`);
if (data?.error) {
throw new Error(data.error + '. Are you logged into creator.xiaohongshu.com?');
}
if (!data?.data) {
throw new Error('Unexpected response structure');
}
const stats = data.data[period];
if (!stats) {
throw new EmptyResultError('xiaohongshu creator-stats', `No data for period "${period}". Available: ${Object.keys(data.data).join(', ')}`);
}
// Format daily trend as sparkline-like summary
const formatTrend = (list) => {
if (!list || !list.length)
return '-';
return list.map((d) => d.count).join(' → ');
};
return [
{ metric: '观看数 (views)', total: stats.view_count ?? 0, trend: formatTrend(stats.view_list) },
{ metric: '平均观看时长 (avg view time ms)', total: stats.view_time_avg ?? 0, trend: formatTrend(stats.view_time_list) },
{ metric: '主页访问 (home views)', total: stats.home_view_count ?? 0, trend: formatTrend(stats.home_view_list) },
{ metric: '点赞数 (likes)', total: stats.like_count ?? 0, trend: formatTrend(stats.like_list) },
{ metric: '收藏数 (collects)', total: stats.collect_count ?? 0, trend: formatTrend(stats.collect_list) },
{ metric: '评论数 (comments)', total: stats.comment_count ?? 0, trend: formatTrend(stats.comment_list) },View on GitHub (pinned to 49907e53dc)
Solutions
- Confirm you are logged into creator.xiaohongshu.com in the automation browser and the dashboard renders
- Inspect the raw evaluate result before the throw to see the actual payload
- Retry — a transient interstitial can produce an empty payload
- Update the in-page parsing script if Xiaohongshu changed its response schema
Example fix
// before
if (!data?.data) {
throw new Error('Unexpected response structure');
}
// after
if (!data?.data) {
throw new Error('Unexpected response structure: ' + JSON.stringify(data).slice(0, 200));
} Defensive patterns
Strategy: type-guard
Type guard
function hasStatsEnvelope(v) { return v !== null && typeof v === 'object' && v.data !== null && typeof v.data === 'object'; } Try / catch
try {
const stats = await getCreatorStats({ period });
} catch (e) {
if (e.message === 'Unexpected response structure') {
// inspect raw payload / re-auth / retry after transient interstitial
} else { throw e; }
} Prevention
- Verify the dashboard loads manually in the same browser profile before automating
- Capture the raw response on failure to catch API shape changes
- Retry once on transient failures (captchas, slow renders)
When it happens
Trigger: The in-page script resolved to null/undefined or an object without `data` — e.g. the stats endpoint returned an HTML error page, an anti-bot interstitial, or the API schema changed.
Common situations: Logged-out or partially authenticated session on creator.xiaohongshu.com; Xiaohongshu backend changed the stats payload shape; transient CDN/captcha responses replacing the JSON body.
Related errors
- Unexpected response structure
- Instagram post feed returned malformed items for ${username}
- Could not find the like control on ${post.code}
- MiniMax music returned a malformed response envelope
- MiniMax music response is missing integer base_resp.status_c
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3ab75d083a427272.
Report an issue: GitHub.