santifer/career-ops · error · Error
jobvite: untrusted hostname "${parsed.hostname}" — must be $
Error message
jobvite: untrusted hostname "${parsed.hostname}" — must be ${BOARD_HOST} or ${FEED_HOST} What it means
Thrown by assertJobviteHost() when a parsed URL is HTTPS but its hostname is not in the ALLOWED_HOSTS set (the Jobvite board host or the XML feed host). The provider hard-pins the two known Jobvite hosts and will not fetch from any other hostname, preventing SSRF via redirect or a tampered entry pointing at an internal or attacker-controlled server.
Source
Thrown at providers/jobvite.mjs:102
// 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
* @returns {string | null}
*/View on GitHub (pinned to 9b17a8ac97)
Solutions
- Confirm the entry is genuinely a Jobvite tenant — open the careers_url in a browser and check it resolves to a Jobvite board.
- If the company migrated off Jobvite, switch the entry's provider to the correct ATS (greenhouse, lever, ashby, etc.) or remove it.
- If it is a valid Jobvite tenant with a custom domain, use the company_eid: field with the canonical app.jobvite.com feed host instead of the vanity URL.
Example fix
// before (portals.yml) — wrong provider/host acme: provider: jobvite careers_url: https://careers.acme.com # not a Jobvite host // after — pin by eId on the canonical Jobvite feed host acme: provider: jobvite company_eid: q6NaVfwI
Defensive patterns
Strategy: validation
Validate before calling
const JOBVITE_HOSTS = new Set(['jobs.jobvite.com', 'app.jobvite.com']);
function isTrustedJobviteHost(url) {
try {
return JOBVITE_HOSTS.has(new URL(url).hostname);
} catch {
return false;
}
} Type guard
/** @param {string} url @returns {boolean} */
function isAllowedJobviteUrl(url) {
try {
const p = new URL(url);
return p.protocol === 'https:' && JOBVITE_HOSTS.has(p.hostname);
} catch {
return false;
}
} Prevention
- Keep a config-time allow-list of expected provider hosts and lint entries against it.
- When a company changes ATS, update the provider field, not just the URL.
- Prefer company_eid: over vanity URLs so the host is always the canonical app.jobvite.com.
When it happens
Trigger: An api: URL whose host is something other than the expected Jobvite hosts (e.g. a lookalike domain, a staging host, an internal IP); a careers_url whose vanity slug resolution produced a host the allow-list rejects; or an attempt to point the provider at a non-Jobvite ATS that happens to share a URL shape.
Common situations: Pointing the jobvite provider at a company that has migrated off Jobvite to a different ATS (the slug now answers a different host); a typo in the careers_url domain; a company that uses a custom CNAME not in the allow-list.
Related errors
- jobvite: URL must use HTTPS: ${url}
- justjoin: untrusted hostname "${parsed.hostname}" — must be
- landingjobs: untrusted hostname "${parsed.hostname}" — must
- flowxtra: untrusted hostname "${parsed.hostname}" — must be
- gem: invalid URL: ${url}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/701604688e40cf9d.
Report an issue: GitHub.