santifer/career-ops · error · Error

jobvite: cannot derive a company id for

Error message

jobvite: cannot derive a company id for ${entry.name} — set company_eid: or an api: URL with ?c=

What it means

jobvite's fetch() needs a companyEId to query the Jobvite API. It first tries resolveConfiguredEid(entry) (the company_eid: field or ?c= on an api: URL); if absent it tries to resolve a slug and scrape the board page for the ID. When neither an eid nor a usable slug exists, it throws this error telling you exactly which config fields to set.

Solutions

  1. Find companyEId in the company's Jobvite board page source (companyEId: '…') and add `company_eid: <id>` to the portals.yml entry.
  2. Alternatively set api: to a URL containing ?c=<companyEid> so resolveConfiguredEid picks it up.
  3. Set careers_url to the canonical https://jobs.jobvite.com/<company-slug> board so resolveSlug can derive the slug and scrape the eid.

Example fix

// before (portals.yml)
provider: jobvite
name: Acme
careers_url: https://acme.com/careers
// after
provider: jobvite
name: Acme
company_eid: "1234567"
Defensive patterns

Strategy: validation

Validate before calling

if (entry.provider === 'jobvite' && !entry.company_eid && !/[?&]c=\d+/.test(entry.api ?? '') && !resolveSlug(entry)) {
  throw new Error(`jobvite entry ${entry.name} needs company_eid:`);
}

Type guard

const hasJobviteId = (entry) => Boolean(entry.company_eid) || /[?&]c=/.test(entry.api ?? '') || /^https:\/\/jobs\.jobvite\.com\/[\w-]+/.test(entry.careers_url ?? '');

Try / catch

try {
  await provider.fetch(entry, ctx);
} catch (e) {
  if (e.message.includes('cannot derive a company id')) {
    console.error(`Add company_eid: to ${entry.name} in portals.yml`);
  }
}

Prevention

When it happens

Trigger: A portals.yml entry with `provider: jobvite` (or auto-detected) that has no company_eid:, an api: URL without ?c=, and no resolvable slug from careers_url — e.g. careers_url points at a company's vanity careers site rather than jobs.jobvite.com/<slug>.

Common situations: Company uses a vanity domain so the slug cannot be derived; config entry added with only a name and a generic homepage URL; migration from another ATS listing where the Jobvite ID was never captured.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/7ad7e6e362abd3c1. Report an issue: GitHub.

Appendix: source

Thrown at providers/jobvite.mjs:300

/** @type {Provider} */
export default {
  id: 'jobvite',

  detect(entry) {
    const eid = resolveConfiguredEid(entry);
    if (eid) return { url: buildFeedUrl(eid) };
    // A vanity URL alone still identifies this provider; the eId is resolved
    // at fetch time via discovery.
    const slug = resolveSlug(entry);
    return slug ? { url: buildBoardUrl(slug) } : null;
  },

  async fetch(entry, ctx) {
    let eid = resolveConfiguredEid(entry);

    if (!eid) {
      const slug = resolveSlug(entry);
      if (!slug) throw new Error(`jobvite: cannot derive a company id for ${entry.name} — set company_eid: or an api: URL with ?c=`);
      const boardUrl = buildBoardFetchUrl(slug);
      assertJobviteHost(boardUrl);
      // redirect:'error' here, not 'manual'. A board that still redirects once
      // fr=true&nl=1 is present is a retired slug answering
      // search.jobvite.com?invalid=1, and that must fail loudly.
      const html = await fetchTextWithRetry(ctx, boardUrl, { redirect: 'error' }, RETRY_POLICY);
      eid = extractEidFromBoard(html);
      if (!eid) {
        throw new Error(
          `jobvite: could not find companyEId on ${boardUrl} for ${entry.name}. ` +
          `Set it explicitly with company_eid: (find it in the board page source as companyEId: '…').`,
        );
      }
    }

    const feedUrl = buildFeedUrl(eid);
    assertJobviteHost(feedUrl);
    try {

View on GitHub (pinned to aac998c7ed)