jackwener/OpenCLI · error · ArgumentError

query is required

Error message

query is required

What it means

The linkedin search command declares `query` as a required positional argument, and the func re-validates it: after trimming, an empty keywords string throws this ArgumentError. The keywords are mandatory because they become the `keywords:` term of the LinkedIn jobs search query.

Source

Thrown at clis/linkedin/search.js:424

        { name: 'location', type: 'string', required: false, help: 'Location text such as San Francisco Bay Area' },
        { name: 'limit', type: 'int', default: 10, help: 'Number of jobs to return (max 100)' },
        { name: 'start', type: 'int', default: 0, help: 'Result offset for pagination' },
        { name: 'details', type: 'bool', default: false, help: 'Include full job description and apply URL (slower)' },
        { name: 'company', type: 'string', required: false, help: 'Comma-separated company names or LinkedIn company IDs' },
        { name: 'experience-level', type: 'string', required: false, help: 'Comma-separated: internship, entry, associate, mid-senior, director, executive' },
        { name: 'job-type', type: 'string', required: false, help: 'Comma-separated: full-time, part-time, contract, temporary, volunteer, internship, other' },
        { name: 'date-posted', type: 'string', required: false, help: 'One of: any, month, week, 24h' },
        { name: 'remote', type: 'string', required: false, help: 'Comma-separated: on-site, hybrid, remote' },
    ],
    columns: ['rank', 'title', 'company', 'location', 'listed', 'salary', 'url'],
    func: async (page, kwargs) => {
        const limit = parseIntegerArg(kwargs.limit, '--limit', 10, MIN_LIMIT, MAX_LIMIT);
        const start = parseIntegerArg(kwargs.start, '--start', 0, MIN_START);
        const includeDetails = Boolean(kwargs.details);
        const location = (kwargs.location ?? '').trim();
        const keywords = String(kwargs.query ?? '').trim();
        if (!keywords)
            throw new ArgumentError('query is required');
        const searchParams = new URLSearchParams({ keywords });
        if (location)
            searchParams.set('location', location);
        await page.goto(`https://www.linkedin.com/jobs/search/?${searchParams.toString()}`);
        await assertLinkedInAuthenticated(page, 'LinkedIn search');
        await page.wait({ text: 'Jobs', timeout: 10 });
        const companyIds = await resolveCompanyIds(page, kwargs.company);
        const input = {
            keywords,
            location,
            limit,
            start,
            companyIds,
            experienceLevels: mapFilterValues(kwargs['experience-level'], EXPERIENCE_LEVELS, 'experience_level'),
            jobTypes: mapFilterValues(kwargs['job-type'], JOB_TYPES, 'job_type'),
            datePostedValues: mapFilterValues(kwargs['date-posted'], DATE_POSTED, 'date_posted'),
            remoteTypes: mapFilterValues(kwargs.remote, REMOTE_TYPES, 'remote'),
        };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a non-empty keywords argument, e.g. `opencli linkedin search "software engineer"`.
  2. If the value comes from a variable, check it is non-empty before invoking; quote it in the shell so it is not swallowed.
  3. If you only want to filter without keywords, you still must supply some search text — use a broad term like 'engineer' combined with --company/--location filters.

Example fix

// before (Q empty -> ArgumentError)
const q = process.env.QUERY || '';
await run(['linkedin', 'search', q]);
// after
const q = (process.env.QUERY || '').trim();
if (!q) throw new Error('QUERY env var must be a non-empty search string');
await run(['linkedin', 'search', q]);
Defensive patterns

Strategy: validation

Validate before calling

const query = (process.argv[2] || '').trim();
if (!query) {
  console.error('Usage: opencli linkedin search <query> [--location ...]');
  process.exit(1);
}
await run(['linkedin', 'search', query]);

Type guard

const hasQuery = (kwargs) =>
  typeof kwargs?.query === 'string' && kwargs.query.trim().length > 0;

Try / catch

try {
  await run(['linkedin', 'search', query]);
} catch (e) {
  if (/query is required/.test(e.message)) {
    console.error('Provide a non-empty search string as the positional argument.');
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `opencli linkedin search` with no positional argument, with an empty string (`--query ""` or positional ""), or with a value that is only whitespace (e.g. ' '), so `String(kwargs.query ?? '').trim()` yields ''. Also occurs when programmatic callers pass kwargs.query as null/undefined.

Common situations: Shell quoting mistakes that drop the argument; scripts interpolating an empty variable (`search "$Q"` with Q unset); wrappers forwarding kwargs without mapping the positional; users assuming other filters alone (e.g. --company) can drive a search.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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