jackwener/OpenCLI · error · CommandExecutionError
${label} returned an unexpected payload shape; expected an o
Error message
${label} returned an unexpected payload shape; expected an object. What it means
assertPlainObject() throws CommandExecutionError when `value` is null, not an object, or an array — i.e., the fetched payload (`label`) is not the expected object shape. It protects downstream property access from shape changes in scraped/API data.
Source
Thrown at clis/autohome/utils.js:120
}
return n;
}
export function requireStableId(value, label) {
const id = String(value ?? '').trim();
if (!/^\d+$/.test(id)) throw new CommandExecutionError(`${label} did not include a stable numeric id.`);
return id;
}
export function requireText(value, label) {
const text = clean(value);
if (!text) throw new CommandExecutionError(`${label} did not include a stable text value.`);
return text;
}
export function assertPlainObject(value, label) {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw new CommandExecutionError(`${label} returned an unexpected payload shape; expected an object.`);
}
return value;
}
/** Fetch an Autohome page as text. The grade + koubei pages are UTF-8. */
export async function ahFetch(url, contextHint) {
let resp;
try {
resp = await fetch(url, {
headers: {
'User-Agent': UA,
Referer: `${AH_BASE}/`,
'Accept-Language': 'zh-CN,zh;q=0.9',
},
});
} catch (err) {
throw new CommandExecutionError(`autohome ${contextHint} network error: ${err?.message || err}`);
}View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect what the payload actually was (log JSON.stringify of it before asserting)
- Retry the fetch — a missing __NEXT_DATA__ is often a transient/interstitial page
- Wrap with your own shape check (plain-object guard) and handle the alternate shape explicitly
Example fix
// before
assertPlainObject(maybeArray, 'bd payload')
// after
if (Array.isArray(maybeArray)) maybeArray = maybeArray[0] ?? {};
assertPlainObject(maybeArray, 'bd payload') Defensive patterns
Strategy: type-guard
Validate before calling
function isPlainObject(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
}
if (!isPlainObject(payload)) throw new Error('Unexpected payload shape'); Type guard
function isPlainObject(v) {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try {
assertPlainObject(payload, 'pageProps');
} catch (err) {
if (err instanceof CommandExecutionError && /unexpected payload shape/.test(err.message)) {
console.error('Payload was:', JSON.stringify(payload)?.slice(0, 200));
} else throw err;
} Prevention
- Log/log a truncated JSON of payloads before asserting so failures are debuggable
- Handle arrays/strings explicitly when an endpoint can return multiple shapes
- Retry fetches when __NEXT_DATA__ is missing — often a transient page variant
When it happens
Trigger: extractPageProps or similar returns null/undefined because __NEXT_DATA__ was absent; a JSON endpoint returns an array or string; a failed fetch produced a non-object placeholder.
Common situations: Autohome changing their Next.js data format; region/anti-bot variants of pages lacking pageProps; feeding raw JSON arrays where objects are expected.
Related errors
- Booking.com extractor returned malformed items
- Booking.com extractor returned malformed hotel row
- douyin hashtag ${action}: API returned malformed "${field}"
- Instagram post feed returned malformed items for ${username}
- LinkedIn jobs preferences returned malformed preferences pay
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/02cf8c32bdf423b4.
Report an issue: GitHub.