{"record":{"id":"a00e16cac0bbc88c","repo":"jackwener/OpenCLI","slug":"error-a00e16","errorCode":null,"errorMessage":"未找到该候选人","messagePattern":"未找到该候选人","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/boss/chatmsg.js","lineNumber":41,"sourceCode":"        time: m.time ? new Date(m.time).toLocaleString('zh-CN') : '',\n    };\n}\n\nfunction mapGeekMsg(m, friend) {\n    const fromUid = m.from && m.from.uid;\n    const isFromBoss = fromUid != null && String(fromUid) === String(friend.uid);\n    return {\n        from: isFromBoss ? '对方' : '我',\n        type: TYPE_MAP[m.type] || `其他(${m.type})`,\n        text: m.text || m.body?.text || m.body?.content || m.body?.showText ||\n            JSON.stringify(m.body || {}).slice(0, 120),\n        time: m.time ? new Date(m.time).toLocaleString('zh-CN') : '',\n    };\n}\n\nasync function bossChatMsg(page, kwargs, existingFriend) {\n    const friend = existingFriend ?? await findFriendByUid(page, kwargs.uid);\n    if (!friend) throw new EmptyResultError('boss chatmsg', '未找到该候选人');\n    if (!friend.securityId) throw new CommandExecutionError('该聊天缺少 securityId，无法获取历史消息');\n    const gid = friend.uid;\n    const securityId = encodeURIComponent(friend.securityId);\n    const msgUrl = `https://www.zhipin.com/wapi/zpchat/boss/historyMsg?gid=${gid}&securityId=${securityId}&page=${kwargs.page}&c=20&src=0`;\n    const msgData = await bossFetch(page, msgUrl);\n    const messages = msgData.zpData?.messages ?? msgData.zpData?.historyMsgList;\n    if (!Array.isArray(messages)) {\n        throw new CommandExecutionError('Boss recruiter history response did not include a message list');\n    }\n    if (messages.length === 0) {\n        throw new EmptyResultError('boss chatmsg', 'Boss returned no messages for this chat.');\n    }\n    return messages.map((m) => mapBossMsg(m, friend));\n}\n\nasync function geekChatMsg(page, kwargs, encryptSystemId) {\n    const friend = await findGeekFriendByUid(page, kwargs.uid, { encryptSystemId });\n    if (!friend) throw new EmptyResultError('boss chatmsg', '未找到该聊天（geek 侧）');","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/boss/chatmsg.js#L23-L59","documentation":"bossChatMsg throws EmptyResultError('boss chatmsg', '未找到该候选人') when neither an existingFriend argument nor findFriendByUid resolves to a chat entry for the given uid. The library throws because it cannot obtain the gid/securityId needed to call the historyMsg API, so returning anything would fabricate data. It signals an empty lookup result, not a network failure.","triggerScenarios":"Calling `boss side=boss chatmsg <uid>` with a uid that is absent from the recruiter's chat list — e.g. a uid taken from the geek (job-seeker) side, a stale uid from an older chatlist run, a typo/truncated encrypted uid, or the conversation having been deleted by the candidate.","commonSituations":"Caching a uid from a previous session after the chat was removed; using a geek-side uid with --side boss; account switched and the new recruiter account has no such conversation; the candidate unmatched/blocked the recruiter so the chat disappeared.","solutions":["Re-run `opencli boss chatlist` and copy a fresh uid from its output; encrypted uids rotate.","Omit --side (use default 'auto') so the command also searches the geek-side chat list before giving up.","Verify the uid string is complete and unmodified (no truncation, quotes, or whitespace) — it must match the encrypted uid column exactly.","Check you are logged into the correct recruiter account that actually has this conversation.","If using side=geek/boss explicitly, confirm the uid exists on that specific side; switch --side accordingly."],"exampleFix":"// before\nopencli boss chatmsg 0x8f3a2b --side boss   // uid only exists on geek side\n// after\nopencli boss chatmsg 0x8f3a2b               // auto mode finds it on the geek side","handlingStrategy":"try-catch","validationCode":"// verify uid exists before fetching messages\nconst friends = await chatlist({});\nconst match = friends.find(f => f.uid === uid);\nif (!match) throw new Error(`uid ${uid} not in current chatlist — refresh it`);","typeGuard":"function isFriend(f) { return !!f && typeof f === 'object' && typeof f.uid === 'string' && f.uid.length > 0; }","tryCatchPattern":"try {\n  const msgs = await chatmsg(uid, { side: 'auto' });\n} catch (e) {\n  if (isEmptyResultError(e)) return []; // treat as no conversation\n  throw e;\n}","preventionTips":["Always take uid values from a fresh `boss chatlist` run; encrypted uids are not stable across sessions.","Prefer side=auto over forcing --side boss so both chat lists are searched.","Quote uids in the shell to avoid character mangling.","Verify the conversation exists in the BOSS web UI when debugging."],"tags":["empty-result","boss-zhipin","chat-history","lookup-failed"],"backgroundTag":"chat-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}