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

  1. Inspect what the payload actually was (log JSON.stringify of it before asserting)
  2. Retry the fetch — a missing __NEXT_DATA__ is often a transient/interstitial page
  3. 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

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


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