jackwener/OpenCLI · error · CommandExecutionError

Boss recommend response did not include zpData.friendList

Error message

Boss recommend response did not include zpData.friendList

What it means

fetchRecommendList calls Boss直聘's greetRecSortList API and expects data.zpData.friendList to be an array of recommended candidates. When the response lacks that field or it is not an array (login expiry, anti-bot gate, API schema change, or code!=0 response shape), the library throws this CommandExecutionError instead of returning a bogus value.

Source

Thrown at clis/boss/utils.js:174

    const jobId = opts.jobId ?? '0';
    const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/getBossFriendListV2.json?page=${pageNum}&status=0&jobId=${jobId}`;
    const data = await bossFetch(page, url, { allowNonZero: opts.allowNonZero });
    if (opts.allowNonZero && data.code !== 0) return data;
    const list = data.zpData?.friendList;
    if (!Array.isArray(list)) {
        throw new CommandExecutionError('Boss friend list response did not include zpData.friendList');
    }
    return list;
}
/**
 * Fetch the recommended candidates (greetRecSortList).
 */
export async function fetchRecommendList(page) {
    const url = `https://${BOSS_DOMAIN}/wapi/zprelation/friend/greetRecSortList`;
    const data = await bossFetch(page, url);
    const list = data.zpData?.friendList;
    if (!Array.isArray(list)) {
        throw new CommandExecutionError('Boss recommend response did not include zpData.friendList');
    }
    return list;
}
/**
 * Find a friend by encryptUid, searching through friend list and optionally greet list.
 * Returns null if not found.
 */
export async function findFriendByUid(page, encryptUid, opts = {}) {
    const maxPages = opts.maxPages ?? 1;
    const checkGreetList = opts.checkGreetList ?? false;
    // Search friend list pages
    for (let p = 1; p <= maxPages; p++) {
        const result = await fetchFriendList(page, { pageNum: p, allowNonZero: opts.allowNonZero });
        if (opts.allowNonZero && !Array.isArray(result)) {
            return { friend: null, code: result.code };
        }
        const friends = Array.isArray(result) ? result : [];
        const found = friends.find((f) => f.encryptUid === encryptUid);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-login to Boss直聘 in the automation page and retry the command
  2. Log the full data object (data.code, data.zpData keys) at the throw site to confirm whether it is an auth/rate-limit envelope vs schema change
  3. Verify you are passing a logged-in page to fetchRecommendList (bossFetch uses that page's cookies)
  4. Pin/update the scraper version if Boss changed the API schema and update the field path

Example fix

// before
const data = await bossFetch(page, url);
const list = data.zpData?.friendList;
// after
const data = await bossFetch(page, url);
if (data.code !== 0) throw new AuthRequiredError(BOSS_DOMAIN, `Boss API code=${data.code}`);
const list = data.zpData?.friendList;
Defensive patterns

Strategy: type-guard

Validate before calling

const cookies = await page.getCookies({ url: `https://${BOSS_DOMAIN}` });
if (!cookies.some(c => c.value)) throw new Error('Not logged in to Boss — login first');

Type guard

function hasFriendList(d) { return Array.isArray(d?.zpData?.friendList); }

Try / catch

try { const list = await fetchRecommendList(page); }
catch (e) { if (e instanceof CommandExecutionError) { await relogin(page); return fetchRecommendList(page); } throw e; }

Prevention

When it happens

Trigger: Calling candidates, friends, or greetList commands when the greetRecSortList endpoint returns a payload without zpData.friendList — e.g. session cookie expired, page not logged in, rate-limited/blocked request, or Boss changed the response schema.

Common situations: Boss session expired after idle; account flagged and WAPI returns an error envelope; scraping without a logged-in Playwright page; upstream API refactor renamed friendList.

Related errors


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