jackwener/OpenCLI · error · CommandExecutionError
${webHost} feed: unexpected items payload shape
Error message
${webHost} feed: unexpected items payload shape What it means
runFeed requires data.items to be an array. If the hydrated object exists but items is missing or not an array, it throws CommandExecutionError 'unexpected items payload shape'. This validates the feed store schema the CLI depends on.
Source
Thrown at clis/xiaohongshu/feed.js:111
/**
* Shared func-mode implementation. Exported so the rednote adapter can run the
* same store read against www.rednote.com without duplicating the logic.
*/
export async function runFeed(page, kwargs, webHost) {
const limit = parseLimit(kwargs.limit);
await page.goto(`https://${webHost}/explore`);
// Pinia store hydrates from SSR; give the page a beat to finish
// bootstrapping before reading the array.
await page.wait({ time: 2 });
const data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));
if (!data || typeof data !== 'object') {
throw new CommandExecutionError(`${webHost} feed: unexpected evaluate response`);
}
if (data.error) {
throw new CommandExecutionError(`${webHost} feed: ${data.error}`, `The SPA may still be hydrating; reload ${webHost}/explore and retry.`);
}
if (!Array.isArray(data.items)) {
throw new CommandExecutionError(`${webHost} feed: unexpected items payload shape`);
}
const rows = [];
for (const row of data.items) {
if (rows.length >= limit)
break;
if (!row || typeof row !== 'object') {
throw new CommandExecutionError(`${webHost} feed: malformed feed item`);
}
const id = toCleanString(row.id);
if (!id) {
throw new CommandExecutionError(`${webHost} feed: feed item is missing note id`);
}
const xsecToken = toCleanString(row.xsecToken);
if (!xsecToken) {
throw new CommandExecutionError(`${webHost} feed: feed item ${id} is missing xsecToken; cannot build a signed drill-down URL`);
}
rows.push({
id,View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the store in DevTools to confirm the current items property name/path
- Update FEEDS_READ_JS to read the new store path
- Retry when the page has fully hydrated so items is populated
- Fall back to another feed/tab if the explore feed shape differs
Example fix
// before (in-page script)
return { items: store.feed.notes };
// after (tolerate alternate shapes)
const raw = store.feed?.notes ?? store.feed?.items ?? [];
return { items: Array.isArray(raw) ? raw : [] }; Defensive patterns
Strategy: type-guard
Validate before calling
const data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));
if (!data || !Array.isArray(data.items)) throw new Error('feed items payload malformed'); Type guard
function hasFeedItems(d) { return !!d && typeof d === 'object' && Array.isArray(d.items); } Try / catch
try {
const rows = await runFeed(page, webHost, limit);
} catch (err) {
if (err instanceof CommandExecutionError && err.message.includes('unexpected items payload shape')) {
// inspect raw store in DevTools; update FEEDS_READ_JS to the new items path
} else throw err;
} Prevention
- Smoke-test FEEDS_READ_JS in DevTools after site deploys
- Normalize alternate item shapes (list/items/notes) inside the in-page script
- Wait for full hydration before reading the store
When it happens
Trigger: page.evaluate(FEEDS_READ_JS) returns an object without an items array, e.g. items is undefined, an object map, or a wrapped { list: [...] } structure after a site update.
Common situations: Xiaohongshu changed their Pinia store shape (renamed/moved items), explore page rendered an empty/error state whose store lacks items, custom feed types with different payloads.
Related errors
- Malformed ${draftType} draft payload
- ${webHost} feed: unexpected evaluate response
- ${webHost} feed: ${data.error}
- ${webHost} feed: malformed feed item
- ${webHost} feed: feed item is missing note id
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7357540ac472bedb.
Report an issue: GitHub.