jackwener/OpenCLI · error · CommandExecutionError

Boss geek friend enrichment response did not include zpData.

Error message

Boss geek friend enrichment response did not include zpData.result

What it means

fetchGeekFriendInfoList enriches geek friends in batches of 50 via POST getGeekFriendList.json and expects each batch response to contain data.zpData.result as an array. A missing/non-array result means the batch response is an error envelope or the API schema changed, so the library throws instead of silently producing partial results.

Source

Thrown at clis/boss/utils.js:441

}
/**
 * Enrich a batch of geek friends with full fields including securityId.
 * Processes in batches of 50 to avoid oversized request bodies.
 */
export async function fetchGeekFriendInfoList(page, friendIds = []) {
    if (!friendIds.length) return [];
    const BATCH_SIZE = 50;
    const results = [];
    for (let i = 0; i < friendIds.length; i += BATCH_SIZE) {
        const batch = friendIds.slice(i, i + BATCH_SIZE).map(String);
        const body = `friendIds=${batch.join(',')}`;
        const data = await bossFetch(page, `https://${BOSS_DOMAIN}/wapi/zprelation/friend/getGeekFriendList.json`, {
            method: 'POST',
            body,
        });
        const batchResult = data.zpData?.result;
        if (!Array.isArray(batchResult)) {
            throw new CommandExecutionError('Boss geek friend enrichment response did not include zpData.result');
        }
        results.push(...batchResult);
    }
    return results;
}
/**
 * Find a geek-side friend by encrypted uid.
 * Merges label-list and enriched data; returns null if not found.
 */
export async function findGeekFriendByUid(page, encryptUid, opts = {}) {
    const labelList = await fetchGeekFriendLabelList(page, { encryptSystemId: opts.encryptSystemId });
    const candidate = labelList.find((f) => f.encryptFriendId === encryptUid ||
        String(f.uid) === String(encryptUid) ||
        String(f.friendId) === String(encryptUid));
    if (!candidate) return null;
    const enriched = await fetchGeekFriendInfoList(page, [candidate.friendId]);
    return { ...candidate, ...(enriched[0] || {}) };
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-login and re-run the enriched command
  2. Check the response data.code/body of the failing batch to identify auth vs throttling vs rejection
  3. Reduce batch size or add delay between batches if throttled
  4. Update the zpData.result path if Boss changed the response schema

Example fix

// before
const batchResult = data.zpData?.result;
if (!Array.isArray(batchResult)) throw new CommandExecutionError('...');
// after
if (data.code !== 0) throw new AuthRequiredError(BOSS_DOMAIN, `getGeekFriendList code=${data.code}`);
const batchResult = data.zpData?.result ?? [];
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the friend list source succeeded first
const friends = await fetchGeekFriendLabelList(page, { labelId, allowNonZero: false });
if (!friends.length) return [];

Type guard

function hasBatchResult(d) { return Array.isArray(d?.zpData?.result); }

Try / catch

try { const enriched = await fetchGeekFriendInfoList(page, friends); }
catch (e) { if (e instanceof CommandExecutionError) { await relogin(page); return fetchGeekFriendInfoList(page, friends); } throw e; }

Prevention

When it happens

Trigger: Calling the enriched command when a batch POST to getGeekFriendList.json returns without zpData.result — expired session, request body rejected (bad uid/securityId in batch), rate limiting, or field renamed by Boss.

Common situations: Long enrichment runs whose session expires mid-batch; friend list containing stale uids the endpoint rejects; anti-bot throttling during rapid batched POSTs; upstream schema change.

Related errors


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