{"record":{"id":"0c7b0d9e189a1070","repo":"santifer/career-ops","slug":"jobvite-could-not-find-companyeid-on-boardurl","errorCode":null,"errorMessage":"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: '…').","messagePattern":"jobvite: could not find companyEId on (.+?) for (.+?)\\. Set it explicitly with company_eid: \\(find it in the board page source as companyEId: '…'\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/jobvite.mjs","lineNumber":303,"sourceCode":"    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 {\n      const xml = await fetchTextWithRetry(\n        ctx,\n        feedUrl,\n        { redirect: 'manual', timeoutMs: FEED_TIMEOUT_MS },\n        RETRY_POLICY,\n      );\n      return parseJobviteXml(xml, entry.name);\n    } catch (err) {\n      // An empty board is reported as a redirect to NoJobs.htm rather than as","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/jobvite.mjs#L285-L321","documentation":"Thrown after the discovery path fetched the Jobvite board page HTML but extractEidFromBoard() could not find the companyEId value in the inline JavaScript. This is the runtime discovery fallback (path 3) failing: the provider made one extra request to scrape the eId from the board page source, and the expected companyEId: '…' token was absent — usually because the board page was redesigned, the slug is retired and serves search.jobvite.com?invalid=1, or the tenant migrated off Jobvite.","triggerScenarios":"A Jobvite vanity slug whose board page no longer contains the companyEId token (board redesign, retired slug, or invalid-redirect page served despite redirect:'error'); an edge case where the inline JS uses a different quoting or variable name than the scraper's regex expects.","commonSituations":"Jobvite shipped a board page redesign that renamed or moved the companyEId assignment; the company left Jobvite so the slug answers an invalid page; a transient full-page error (maintenance, WAF) that returned HTML without the token.","solutions":["Set company_eid: explicitly on the entry (open the board page, view source, copy the companyEId value) to skip discovery entirely.","Confirm the slug is still a live Jobvite tenant by opening the board URL in a browser; if it redirects to search.jobvite.com?invalid=1, the tenant is gone.","If the board page structure changed, update extractEidFromBoard's regex to match the new companyEId assignment shape."],"exampleFix":"# before — relies on discovery, which broke\nacme:\n  provider: jobvite\n  careers_url: https://jobs.jobvite.com/acme\n\n# after — pin the eId, discovery is bypassed\nacme:\n  provider: jobvite\n  careers_url: https://jobs.jobvite.com/acme\n  company_eid: q6NaVfwI","handlingStrategy":"validation","validationCode":"// Verify the board page exposes companyEId before relying on discovery.\nasync function boardExposesEid(fetchText, boardUrl) {\n  const html = await fetchText(boardUrl);\n  return /companyEId\\s*:\\s*['\"][^'\"]+['\"]/i.test(html);\n}","typeGuard":null,"tryCatchPattern":"try {\n  jobs = await provider.fetch(entry, ctx);\n} catch (err) {\n  if (/could not find companyEId/.test(err.message)) {\n    console.error(`${entry.name}: discovery failed — set company_eid manually`);\n  }\n  throw err;\n}","preventionTips":["Pin company_eid: in config for every Jobvite tenant so discovery is never the failure surface.","When discovery fails, view-source on the board page to find the current companyEId token shape.","Treat discovery as a convenience, not a contract — it breaks on board redesigns."],"tags":["jobvite","discovery","scraping","company-eid","board-redesign"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}