jackwener/OpenCLI · error · CommandExecutionError

${label} returned a non-array data field

Error message

${label} returned a non-array data field

What it means

readDataArray in clis/juejin/utils.js:133 additionally requires `payload.data` to be an array. Some Juejin endpoints return `data` as an object (e.g. `{ list: [...], cursor: ... }`) or a scalar; when that happens this CommandExecutionError is thrown instead of letting a downstream `.map()` crash with an opaque TypeError.

Source

Thrown at clis/juejin/utils.js:133

        payload = await resp.json();
    } catch (err) {
        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);
    }
    if (!payload || typeof payload !== 'object' || Array.isArray(payload) || !Object.hasOwn(payload, 'err_no')) {
        throw new CommandExecutionError(`${label} returned a malformed API envelope`);
    }
    if (payload.err_no !== 0) {
        throw new CommandExecutionError(`${label} returned err_no ${payload.err_no}: ${payload.err_msg ?? ''}`);
    }
    return payload;
}

export function readDataArray(payload, label) {
    if (!payload || typeof payload !== 'object' || Array.isArray(payload) || !Object.hasOwn(payload, 'data')) {
        throw new CommandExecutionError(`${label} returned a malformed payload`);
    }
    if (!Array.isArray(payload.data)) {
        throw new CommandExecutionError(`${label} returned a non-array data field`);
    }
    if (payload.data.length === 0) {
        throw new EmptyResultError(label, `${label} returned no articles.`);
    }
    return payload.data;
}

function readArticleId(value, label) {
    const id = String(value ?? '').trim();
    if (!JUEJIN_ID.test(id)) {
        throw new CommandExecutionError(`${label} returned a malformed article id`);
    }
    return id;
}

function readOptionalNumber(value, label) {
    if (value == null) return null;
    const n = Number(value);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect the actual payload: if `data` is `{ list: [...] }`, unwrap it (`payload.data.list`) before or instead of calling readDataArray.
  2. Use the correct helper for the endpoint shape — a detail/object endpoint should not go through readDataArray.
  3. Update the adapter mapping code if Juejin changed the endpoint to a paginated object envelope.
  4. Add a one-off normalization (e.g. `const rows = Array.isArray(p.data) ? p.data : p.data.list`) while migrating.

Example fix

// before
const rows = readDataArray(payload, 'juejin hot'); // data is { list: [...] }
// after
const raw = Array.isArray(payload.data) ? payload.data : payload.data?.list;
const rows = readDataArray({ ...payload, data: raw }, 'juejin hot');
Defensive patterns

Strategy: type-guard

Validate before calling

const payload = JSON.parse(body);
if (!Array.isArray(payload?.data)) {
  // unwrap paginated object envelope before consuming
  payload.data = payload.data?.list ?? payload.data;
}

Type guard

function isDataArray(p) {
  return p !== null && typeof p === 'object' && Array.isArray(p.data);
}

Try / catch

try {
  const rows = readDataArray(payload, 'juejin list');
} catch (err) {
  if (err instanceof CommandExecutionError && err.message.includes('non-array data field')) {
    const unwrapped = payload.data?.list ?? [];
    processItems(unwrapped); // handle paginated object envelope
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling readDataArray on a payload whose `data` field is an object, string, or null — typically when an endpoint that returns a plain array is swapped for one that wraps results (like `{ data: { list: [...] } }`), or the API changes the data container type.

Common situations: Pointing the adapter at a different Juejin endpoint whose envelope nests the array one level deeper; Juejin migrating a list endpoint to a paginated object response; copy-pasting readDataArray usage onto a detail endpoint that returns a single object.

Related errors


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