{"record":{"id":"7ad7e6e362abd3c1","repo":"santifer/career-ops","slug":"jobvite-cannot-derive-a-company-id-for-entry-na","errorCode":null,"errorMessage":"jobvite: cannot derive a company id for ${entry.name} — set company_eid: or an api: URL with ?c=","messagePattern":"jobvite: cannot derive a company id for (.+?) — set company_eid: or an api: URL with \\?c=","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/jobvite.mjs","lineNumber":300,"sourceCode":"/** @type {Provider} */\nexport default {\n  id: 'jobvite',\n\n  detect(entry) {\n    const eid = resolveConfiguredEid(entry);\n    if (eid) return { url: buildFeedUrl(eid) };\n    // A vanity URL alone still identifies this provider; the eId is resolved\n    // at fetch time via discovery.\n    const slug = resolveSlug(entry);\n    return slug ? { url: buildBoardUrl(slug) } : null;\n  },\n\n  async fetch(entry, ctx) {\n    let eid = resolveConfiguredEid(entry);\n\n    if (!eid) {\n      const slug = resolveSlug(entry);\n      if (!slug) throw new Error(`jobvite: cannot derive a company id for ${entry.name} — set company_eid: or an api: URL with ?c=`);\n      const boardUrl = buildBoardFetchUrl(slug);\n      assertJobviteHost(boardUrl);\n      // redirect:'error' here, not 'manual'. A board that still redirects once\n      // fr=true&nl=1 is present is a retired slug answering\n      // search.jobvite.com?invalid=1, and that must fail loudly.\n      const html = await fetchTextWithRetry(ctx, boardUrl, { redirect: 'error' }, RETRY_POLICY);\n      eid = extractEidFromBoard(html);\n      if (!eid) {\n        throw new Error(\n          `jobvite: could not find companyEId on ${boardUrl} for ${entry.name}. ` +\n          `Set it explicitly with company_eid: (find it in the board page source as companyEId: '…').`,\n        );\n      }\n    }\n\n    const feedUrl = buildFeedUrl(eid);\n    assertJobviteHost(feedUrl);\n    try {","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/jobvite.mjs#L282-L318","documentation":"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.","triggerScenarios":"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>.","commonSituations":"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.","solutions":["Find companyEId in the company's Jobvite board page source (companyEId: '…') and add `company_eid: <id>` to the portals.yml entry.","Alternatively set api: to a URL containing ?c=<companyEid> so resolveConfiguredEid picks it up.","Set careers_url to the canonical https://jobs.jobvite.com/<company-slug> board so resolveSlug can derive the slug and scrape the eid."],"exampleFix":"// before (portals.yml)\nprovider: jobvite\nname: Acme\ncareers_url: https://acme.com/careers\n// after\nprovider: jobvite\nname: Acme\ncompany_eid: \"1234567\"","handlingStrategy":"validation","validationCode":"if (entry.provider === 'jobvite' && !entry.company_eid && !/[?&]c=\\d+/.test(entry.api ?? '') && !resolveSlug(entry)) {\n  throw new Error(`jobvite entry ${entry.name} needs company_eid:`);\n}","typeGuard":"const hasJobviteId = (entry) => Boolean(entry.company_eid) || /[?&]c=/.test(entry.api ?? '') || /^https:\\/\\/jobs\\.jobvite\\.com\\/[\\w-]+/.test(entry.careers_url ?? '');","tryCatchPattern":"try {\n  await provider.fetch(entry, ctx);\n} catch (e) {\n  if (e.message.includes('cannot derive a company id')) {\n    console.error(`Add company_eid: to ${entry.name} in portals.yml`);\n  }\n}","preventionTips":["When onboarding a Jobvite company, always capture companyEId from the board page source into company_eid:.","Never rely on slug scraping for production scans; treat company_eid as required config.","Keep api: URLs with the ?c= parameter if you use feed endpoints directly."],"tags":["missing-config","jobvite","config","company-id"],"backgroundTag":"missing-required-config-field","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}