jackwener/OpenCLI · error · CliError
INVALID_ARGUMENT
INVALID_ARGUMENT
Error message
jobId is required
What it means
The 51job job detail command validates that a jobId argument was supplied; when kwargs.jobId is missing, null, or an empty/whitespace string after trim, it throws CliError('INVALID_ARGUMENT'). This is an input-validation failure thrown synchronously before any navigation or network work.
Source
Thrown at clis/51job/detail.js:35
description: '51job 职位详情(按 jobId)',
domain: 'jobs.51job.com',
strategy: Strategy.COOKIE,
browser: true,
navigateBefore: false,
args: [
{ name: 'jobId', type: 'string', required: true, positional: true, help: '职位 ID(search 返回的 jobId)' },
],
columns: [
'jobId', 'title', 'salary', 'location', 'workYear', 'degree',
'category', 'address', 'ageRequirement',
'description', 'welfare',
'company', 'companyType', 'companySize', 'companyIndustry',
'companyUrl', 'url',
],
func: async (page, kwargs) => {
requirePage(page);
const jobId = String(kwargs.jobId ?? '').trim();
if (!jobId) throw new CliError('INVALID_ARGUMENT', 'jobId is required');
if (!/^\d{6,12}$/.test(jobId)) throw new CliError('INVALID_ARGUMENT', `jobId must be a 6-12 digit number, got "${jobId}"`);
const url = `${JOBS_ORIGIN}/x/${jobId}.html`;
await navigateTo(page, url, 2);
const script = `(() => {
const sel = s => document.querySelector(s)?.innerText?.trim() || '';
const all = s => [...document.querySelectorAll(s)].map(e => e.innerText.trim()).filter(Boolean);
const finalUrl = window.location.href;
const bodyText = (document.body.innerText || '').slice(0, 400);
if (/职位已下线|该职位已删除|页面不存在/.test(bodyText)) {
return { error: 'EXPIRED', bodyText };
}
const companyA = document.querySelector('.cname a, .tCompany_sidebar .com_msg a');
const funcs = all('.bmsg .fp');
const pick = (prefix) => {
const row = funcs.find(f => f.startsWith(prefix));
return row ? row.slice(prefix.length).replace(/^[::\\s\\n]+/, '').trim() : '';View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a valid jobId string/number in the call arguments
- Check the property name is exactly jobId (not id/jobID)
- Guard upstream data: skip or log items without an id before calling detail
- If ids come from a search result, ensure the mapping step copies the id field
Example fix
// before
await cli.detail({ id: job.id });
// after
if (!job.jobId) throw new Error('missing jobId for ' + job.title);
await cli.detail({ jobId: job.jobId }); Defensive patterns
Strategy: validation
Validate before calling
const jobId = String(job?.jobId ?? '').trim();
if (!jobId) throw new Error('jobId is required before calling detail'); Type guard
const hasJobId = (j) => j != null && String(j.jobId ?? '').trim() !== '';
Try / catch
try {
return await cli.detail({ jobId });
} catch (e) {
if (e.code === 'INVALID_ARGUMENT') { console.warn('skip: missing jobId'); return null; }
throw e;
} Prevention
- Always pass the argument key exactly as jobId
- Filter out items lacking ids upstream
- Typecheck call sites if using a typed wrapper
- Never build kwargs dynamically without a presence check
When it happens
Trigger: Calling the detail subcommand without jobId, or with jobId as undefined/null/'' (e.g. String(kwargs.jobId ?? '').trim() yields empty) — thrown at clis/51job/detail.js:35.
Common situations: Programmatic callers piping results where an upstream job item lacked an id; building the call from config where the jobId key is misspelled; passing a variable that is undefined due to a failed destructure.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- INVALID_ARGUMENT
- INVALID_ARGUMENT
- INVALID_ARGUMENT
- INVALID_ARGUMENT
- Unknown privacy "${privacy}". Valid: ${PRIVACY.join(', ')}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/54de0ba6aaa2df65.
Report an issue: GitHub.