santifer/career-ops · error · Error

jobvite: URL must use HTTPS

Error message

jobvite: URL must use HTTPS: ${url}

What it means

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.

Solutions

  1. Change the scheme to https:// in the portals.yml entry.
  2. Remove the explicit api:/careers_url override and set company_eid: so the provider builds the canonical https:// jobs.jobvite.com URL.
  3. Confirm the host is jobs.jobvite.com (board) or the feed host so the following allowlist check passes.

Example fix

// before
const boardUrl = 'http://jobs.jobvite.com/acme';
// after
const boardUrl = 'https://jobs.jobvite.com/acme';
Defensive patterns

Strategy: validation

Validate before calling

if (new URL(entry.api).protocol !== 'https:') throw new Error('jobvite URLs must be https');

Type guard

const isHttps = (s) => { try { return new URL(s).protocol === 'https:'; } catch { return false; } };

Try / catch

try {
  await provider.fetch(entry, ctx);
} catch (e) {
  if (e.message.includes('jobvite: URL must use HTTPS')) {
    entry.api = entry.api.replace(/^http:\/\//, 'https://');
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: Older HTTP links collected before Jobvite enforced HTTPS; internal staging URLs over http; hand-editing the config and dropping the 's'.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at providers/jobvite.mjs:106

// 1.88 MB for 236 jobs in ~11s. That overshoots the shared 10s default in
// _http.mjs by a second, which aborted the whole tenant and reported it as a
// network failure. Sized to absorb a genuinely big tenant on a slow link; the
// board page (a normal HTML document) keeps the default.
const FEED_TIMEOUT_MS = 45_000;

/**
 * Pin a URL to the two known Jobvite hosts over HTTPS.
 * @param {string} url
 */
function assertJobviteHost(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`jobvite: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:')
    throw new Error(`jobvite: URL must use HTTPS: ${url}`);
  if (!ALLOWED_HOSTS.has(parsed.hostname))
    throw new Error(`jobvite: untrusted hostname "${parsed.hostname}" — must be ${BOARD_HOST} or ${FEED_HOST}`);
  return url;
}

// NaN-safe Date.parse → epoch ms.
/** @param {string} value */
function toEpochMs(value) {
  if (!value) return undefined;
  const parsed = Date.parse(value);
  return Number.isNaN(parsed) ? undefined : parsed;
}

/**
 * The vanity slug from a Jobvite careers URL, or null.
 * Only used to build the board URL for eId discovery.
 *
 * @param {import('./_types.js').PortalEntry} entry

View on GitHub (pinned to aac998c7ed)