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
- Re-login to Boss直聘 in the automation page and retry the command
- 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
- Verify you are passing a logged-in page to fetchRecommendList (bossFetch uses that page's cookies)
- 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
- Persist and restore login cookies (storageState) between runs
- Check data.code before reading zpData fields
- Log the raw response when the shape guard fails to detect schema changes early
- Retry once after re-login before surfacing the error
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
- Boss geek chat list response did not include zpData.friendLi
- Boss geek friend enrichment response did not include zpData.
- Boss geek history response did not include a message list
- Bilibili view API did not return cid/up_mid for ${bvid}
- 该聊天缺少 securityId,无法获取历史消息
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2b793701ca88b845.
Report an issue: GitHub.