{"record":{"id":"7e3d8d9f1c7d4eed","repo":"jackwener/OpenCLI","slug":"boss","errorCode":null,"errorMessage":"该命令仅支持招聘端（BOSS 端）账号，请使用招聘者账号登录后重试。","messagePattern":"该命令仅支持招聘端（BOSS 端）账号，请使用招聘者账号登录后重试。","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/boss/utils.js","lineNumber":78,"sourceCode":"}\nfunction checkEnvironment(data) {\n    const message = String(data.message || '').toLowerCase();\n    if (data.code === AMBIGUOUS_AUTH_CODE &&\n        ENVIRONMENT_REJECTED_MARKERS.some((marker) => message.includes(marker.toLowerCase()))) {\n        throw new CommandExecutionError(`Boss rejected the current browser environment: ${data.message || 'Unknown error'} (code=${data.code})`, '重新登录通常无法解决此问题。请保留当前页面，稍后重试，并在问题持续时上报完整错误信息。');\n    }\n}\n/**\n * Map BOSS code=24 (\"请切换身份后再试\") to a typed AuthRequiredError.\n * Recruiter-only commands (recommend, joblist, stats, resume, mark,\n * exchange, invite, greet, batchgreet) have no geek-side equivalent;\n * surfacing this as a generic COMMAND_EXEC hides what the user must do.\n * chatlist / chatmsg avoid this path by using `allowNonZero: true` and\n * branching to the geek-side fetch when they see code 24.\n */\nfunction checkRecruiterSide(data) {\n    if (data.code === IDENTITY_MISMATCH_CODE) {\n        throw new AuthRequiredError(BOSS_DOMAIN, RECRUITER_ONLY_MSG);\n    }\n}\n/**\n * Throw if the API response is not code 0.\n * Checks for cookie expiry first, then identity mismatch, then throws\n * with the provided message.\n */\nexport function assertOk(data, errorPrefix) {\n    if (!data || typeof data !== 'object') {\n        throw new CommandExecutionError(`${errorPrefix ? `${errorPrefix}: ` : ''}Boss API returned malformed response`);\n    }\n    if (data.code === 0)\n        return;\n    checkEnvironment(data);\n    checkAuth(data);\n    checkRecruiterSide(data);\n    const prefix = errorPrefix ? `${errorPrefix}: ` : '';\n    throw new CommandExecutionError(`${prefix}${data.message || 'Unknown error'} (code=${data.code})`);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/boss/utils.js#L60-L96","documentation":"checkRecruiterSide maps BOSS API code 24 ('请切换身份后再试') to AuthRequiredError with a recruiter-only message. Several endpoints (recommend, joblist, stats, resume, mark, exchange, invite, greet, batchgreet) exist only for the recruiter (BOSS) side; calling them while logged in as a job-seeker (geek) returns code 24. Geek-side commands (chatlist/chatmsg) intentionally bypass this via allowNonZero and branch to the geek fetch instead.","triggerScenarios":"Running a recruiter-only command (e.g. `joblist`, `recommend`, `greet`) while the attached Chrome is logged into BOSS as a job-seeker (geek) account; the wapi endpoint replies code 24 identity mismatch.","commonSituations":"Sharing one Chrome profile between geek-side and boss-side commands; switching account type on zhipin.com and forgetting which identity is active; a company account that is primarily a seeker account.","solutions":["Log out of the geek account and log in with a recruiter (BOSS 端) account in the automation Chrome, then rerun.","Verify which account type the current session is (the '切换身份' toggle on zhipin.com) before running recruiter-only commands.","If you intended geek-side chat data, use the geek commands (chatlist/chatmsg) which handle code 24 by switching to the geek-side API instead."],"exampleFix":"// before\ncli greet --uid abc123   # logged in as geek -> code 24\n// after\n# switch the driven Chrome session to the recruiter account, then:\ncli greet --uid abc123","handlingStrategy":"try-catch","validationCode":"const probe = await bossFetch(page, recruiterOnlyProbeUrl, { allowNonZero: true });\nif (probe.code === 24) {\n  console.error('Current session is a job-seeker (geek) account; recruiter commands need a BOSS-side login.');\n  process.exit(1);\n}","typeGuard":"function isIdentityMismatch(data) {\n  return !!data && typeof data === 'object' && data.code === 24;\n}","tryCatchPattern":"try {\n  await cli.joblist();\n} catch (e) {\n  if (e instanceof AuthRequiredError && /仅支持招聘端/.test(e.message)) {\n    console.error('Switch the automation Chrome to a recruiter (BOSS-side) account and retry.');\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Keep dedicated Chrome profiles per account type (recruiter vs geek)","Check the active identity on zhipin.com before running side-specific commands","Use geek-side commands (chatlist/chatmsg) when operating as a job-seeker"],"tags":["auth","wrong-account-type","recruiter-only","identity-mismatch"],"backgroundTag":"wrong-account-type","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}