{"record":{"id":"33e70187e11e8055","repo":"santifer/career-ops","slug":"jobvite-url-must-use-https-url","errorCode":null,"errorMessage":"jobvite: URL must use HTTPS: ${url}","messagePattern":"jobvite: URL must use HTTPS: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/jobvite.mjs","lineNumber":106,"sourceCode":"// 1.88 MB for 236 jobs in ~11s. That overshoots the shared 10s default in\n// _http.mjs by a second, which aborted the whole tenant and reported it as a\n// network failure. Sized to absorb a genuinely big tenant on a slow link; the\n// board page (a normal HTML document) keeps the default.\nconst FEED_TIMEOUT_MS = 45_000;\n\n/**\n * Pin a URL to the two known Jobvite hosts over HTTPS.\n * @param {string} url\n */\nfunction assertJobviteHost(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`jobvite: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:')\n    throw new Error(`jobvite: URL must use HTTPS: ${url}`);\n  if (!ALLOWED_HOSTS.has(parsed.hostname))\n    throw new Error(`jobvite: untrusted hostname \"${parsed.hostname}\" — must be ${BOARD_HOST} or ${FEED_HOST}`);\n  return url;\n}\n\n// NaN-safe Date.parse → epoch ms.\n/** @param {string} value */\nfunction toEpochMs(value) {\n  if (!value) return undefined;\n  const parsed = Date.parse(value);\n  return Number.isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * The vanity slug from a Jobvite careers URL, or null.\n * Only used to build the board URL for eId discovery.\n *\n * @param {import('./_types.js').PortalEntry} entry","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/jobvite.mjs#L88-L124","documentation":"assertJobviteHost() requires the https: protocol on any jobvite board or feed URL. A URL that parses but uses http: (or another scheme like ftp:) throws this error, as part of SSRF/transport-security hardening in the provider.","triggerScenarios":"A portals.yml jobvite entry with `api: http://jobs.jobvite.com/acme` or a feed URL written with http://, then provider fetch() calls assertJobviteHost on the constructed URL.","commonSituations":"Older HTTP links collected before Jobvite enforced HTTPS; internal staging URLs over http; hand-editing the config and dropping the 's'.","solutions":["Change the scheme to https:// in the portals.yml entry.","Remove the explicit api:/careers_url override and set company_eid: so the provider builds the canonical https:// jobs.jobvite.com URL.","Confirm the host is jobs.jobvite.com (board) or the feed host so the following allowlist check passes."],"exampleFix":"// before\nconst boardUrl = 'http://jobs.jobvite.com/acme';\n// after\nconst boardUrl = 'https://jobs.jobvite.com/acme';","handlingStrategy":"validation","validationCode":"if (new URL(entry.api).protocol !== 'https:') throw new Error('jobvite URLs must be https');","typeGuard":"const isHttps = (s) => { try { return new URL(s).protocol === 'https:'; } catch { return false; } };","tryCatchPattern":"try {\n  await provider.fetch(entry, ctx);\n} catch (e) {\n  if (e.message.includes('jobvite: URL must use HTTPS')) {\n    entry.api = entry.api.replace(/^http:\\/\\//, 'https://');\n  }\n}","preventionTips":["Normalize all legacy http:// links to https:// when importing portal configs.","Jobvite no longer serves boards over plain HTTP — never configure http:.","Run a one-time script to rewrite scheme for all jobvite entries."],"tags":["https","url-validation","ssrf-protection","jobvite"],"backgroundTag":"invalid-url","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"}