{"record":{"id":"3a3f2a1bd155ae0c","repo":"jackwener/OpenCLI","slug":"error-3a3f2a","errorCode":null,"errorMessage":"无法在聊天列表中找到该用户，候选人可能不在当前列表中","messagePattern":"无法在聊天列表中找到该用户，候选人可能不在当前列表中","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clis/boss/greet.js","lineNumber":38,"sourceCode":"    ],\n    columns: ['status', 'detail'],\n    func: async (page, kwargs) => {\n        requirePage(page);\n        verbose(`Greeting candidate ${kwargs.uid}...`);\n        await navigateToChat(page, 3);\n        // Find candidate in greet list or friend list\n        const friend = await findFriendByUid(page, kwargs.uid, {\n            maxPages: 1,\n            checkGreetList: true,\n        });\n        if (!friend) {\n            throw new Error('未找到该候选人，请确认 uid 是否正确（可从 recommend 命令获取）');\n        }\n        const numericUid = friend.uid;\n        const friendName = friend.name || '候选人';\n        const clicked = await clickCandidateInList(page, numericUid);\n        if (!clicked) {\n            throw new Error('无法在聊天列表中找到该用户，候选人可能不在当前列表中');\n        }\n        await page.wait({ time: 2 });\n        const msgText = kwargs.text || '你好，请问您对这个职位感兴趣吗？';\n        const sent = await typeAndSendMessage(page, msgText);\n        if (!sent) {\n            throw new Error('找不到消息输入框');\n        }\n        await page.wait({ time: 1 });\n        return [{ status: '✅ 招呼已发送', detail: `已向 ${friendName} 发送: ${msgText}` }];\n    },\n});\n","sourceCodeStart":20,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/boss/greet.js#L20-L50","documentation":"In `opencli boss greet`, after the candidate record is found, the command tries clickCandidateInList(numericUid) to actually open the chat. If the DOM click fails — the row is not rendered in the current chat list view even though the record was found — it throws '无法在聊天列表中找到该用户'. This separates 'found in data' from 'clickable in the UI'.","triggerScenarios":"findFriendByUid succeeded (e.g. from greet-list data) but the candidate's row is not present/rendered in the currently displayed chat list DOM, so clickCandidateInList returns false — e.g. greet-list-only entries not shown in chat list, list re-sorted between find and click, or virtualized list not rendering the row.","commonSituations":"Candidate exists only in the greet list (never chatted) so there is no chat-list row to click; UI list refreshed/filtered between lookup and click; slow rendering so the row wasn't mounted when the click ran.","solutions":["Re-run the command — the list may render the row after a refresh.","Open the chat with the candidate manually in the browser once so a chat-list row exists, then retry.","Retry shortly after `opencli boss recommend` so the candidate is at the top of the greet/chat list.","Check for BOSS UI changes/filters (e.g. a list filter hiding the candidate) in the open browser session."],"exampleFix":"// before\nopencli boss greet <uid>            # greet-list-only candidate\n// after\n# initiate first contact from recommend flow, then:\nopencli boss greet <uid>","handlingStrategy":"retry","validationCode":"// Check the candidate has a chat-list entry (not greet-list only) before greeting:\n// if `opencli boss resume <uid>` also fails with 未找到, there is no row to click yet.\nconst hasChatEntry = await canFindInChatList(uid);","typeGuard":null,"tryCatchPattern":"try {\n  await run(['opencli', 'boss', 'greet', uid, '--text', msg]);\n} catch (e) {\n  if (e.message.includes('无法在聊天列表中找到该用户')) {\n    await sleep(2000); // let the chat list render\n    await run(['opencli', 'boss', 'greet', uid, '--text', msg]); // retry once\n  } else throw e;\n}","preventionTips":["Retry once after a short delay — this is often a render timing issue.","Establish a chat entry first (candidate must be chatted, not greet-only).","Avoid list filters/sorting changes in the browser session between lookup and click.","Keep the BOSS browser session logged in and idle-free."],"tags":["dom-click-failed","boss","chat-list","ui-automation"],"backgroundTag":"element-not-clickable","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}