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

  1. Confirm you are logged into creator.xiaohongshu.com in the automation browser and the dashboard renders
  2. Inspect the raw evaluate result before the throw to see the actual payload
  3. Retry — a transient interstitial can produce an empty payload
  4. 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

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


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