jackwener/OpenCLI · error · CommandExecutionError

LinkedIn job detail could not find a job title

Error message

LinkedIn job detail could not find a job title

What it means

After confirming the extraction row is an object, normalizeDetail normalizes row.title and requires a non-empty job title. If the title is missing or whitespace-only, a CommandExecutionError is thrown since title is the mandatory core of the job-detail result. The row existed, but its essential field did not.

Source

Thrown at clis/linkedin/job-detail.js:124

      company,
      company_url,
      location: locationLine,
      workplace_type: workplaceMatch ? workplaceMatch[1] : '',
      job_type: jobTypeMatch ? jobTypeMatch[1] : '',
      applicants: applicantsMatch ? applicantsMatch[1] : '',
      listed: listedMatch ? listedMatch[1] : '',
      apply_url,
      description,
    };
  })()`;
}

function normalizeDetail(row) {
  if (!row || typeof row !== 'object') {
    throw new CommandExecutionError('LinkedIn job detail returned malformed extraction payload');
  }
  const title = normalizeWhitespace(row.title);
  if (!title) throw new CommandExecutionError('LinkedIn job detail could not find a job title');
  return {
    title,
    company: normalizeWhitespace(row.company),
    location: normalizeWhitespace(row.location),
    workplace_type: normalizeWhitespace(row.workplace_type),
    job_type: normalizeWhitespace(row.job_type),
    applicants: normalizeWhitespace(row.applicants),
    listed: normalizeWhitespace(row.listed),
    apply_url: decodeLinkedinRedirect(normalizeWhitespace(row.apply_url)),
    company_url: normalizeHttpUrl(row.company_url),
    url: normalizeHttpUrl(row.url),
    description: normalizeWhitespace(row.description),
  };
}

cli({
  site: 'linkedin',
  name: 'job-detail',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run; if the page was mid-hydration the title may populate on a second attempt.
  2. Confirm the job page displays a title manually in the same browser profile; expired/rare jobs may render empty shells.
  3. If the page shows a title but the CLI still fails, the extraction selector for title is stale — update/report the library.
  4. As a workaround, fall back to search-results data or another field if your workflow can tolerate a degraded title source.

Example fix

// before
const d = jobDetail(url); // CommandExecutionError: could not find a job title

// after
try { var d = jobDetail(url); }
catch (e) {
  if (e instanceof CommandExecutionError) { await sleep(3000); d = jobDetail(url); }
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForSelector('h1, [class*="job-title"], .top-card-layout__title', { timeout: 15000 });
// only invoke once a title node exists in the DOM

Type guard

const hasTitle = (row) => row != null && typeof row === 'object' && typeof row.title === 'string' && row.title.trim().length > 0;

Try / catch

try {
  return await linkedinJobDetail(jobUrl);
} catch (e) {
  if (e instanceof CommandExecutionError && /could not find a job title/.test(e.message)) {
    await sleep(3000); // let SPA hydration finish
    return linkedinJobDetail(jobUrl);
  }
  throw e;
}

Prevention

When it happens

Trigger: During `linkedin job-detail`, the extraction script returns an object whose title field is absent, null, or only whitespace — e.g. the selector matched a container that doesn't hold the job title on the current LinkedIn layout.

Common situations: LinkedIn A/B tests or redesign moving/renaming the title element so the extractor grabs an empty node, job cards with the title rendered only in a modal after hydration, expired jobs rendering skeleton markup with empty fields.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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