santifer/career-ops · error · Error
jobvite: untrusted hostname
Error message
jobvite: untrusted hostname "${parsed.hostname}" — must be ${BOARD_HOST} or ${FEED_HOST} What it means
assertJobviteHost() accepts only two hostnames: BOARD_HOST (jobs.jobvite.com) and FEED_HOST (Jobvite's feed host). Any other parsed hostname throws this untrusted-hostname error, preventing SSRF through a user-controlled careers_url or api URL.
Solutions
- Point the URL at https://jobs.jobvite.com/<company-slug> (or the feed host) exactly.
- Set company_eid: on the entry so fetch() builds the allowlisted URL from the ID rather than trusting a custom host.
- If you have a legitimate third host, update ALLOWED_HOSTS / BOARD_HOST / FEED_HOST constants in providers/jobvite.mjs deliberately.
Example fix
// before (portals.yml) provider: jobvite careers_url: https://careers.acme.com/jobs // after provider: jobvite careers_url: https://jobs.jobvite.com/acme
Defensive patterns
Strategy: validation
Validate before calling
const host = new URL(entry.careers_url).hostname;
if (host !== 'jobs.jobvite.com' && host !== FEED_HOST) throw new Error(`${host} is not a jobvite board host`); Type guard
const isJobviteUrl = (s) => { try { return ['jobs.jobvite.com', FEED_HOST].includes(new URL(s).hostname); } catch { return false; } }; Try / catch
try {
await provider.fetch(entry, ctx);
} catch (e) {
if (e.message.includes('jobvite: untrusted hostname')) {
entry.careers_url = `https://jobs.jobvite.com/${entry.slug ?? entry.name.toLowerCase()}`;
}
} Prevention
- Use only jobs.jobvite.com board URLs or the official feed host in config.
- If a company uses a vanity careers domain, find its underlying jobs.jobvite.com board instead.
- Set company_eid: so the provider constructs the URL itself.
When it happens
Trigger: A jobvite entry whose api:/careers_url points at another domain — e.g. search.jobvite.com, a custom vanity domain, or a lookalike host; or a slug was embedded into the wrong base URL by custom code.
Common situations: Copying a jobvite URL from a company's own website that uses a vanity CNAME; using search.jobvite.com?invalid=1 style links from a retired board; typo'd hostnames.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- jobstreet: untrusted hostname
- landingjobs: untrusted hostname
- larajobs: untrusted hostname
- lever: untrusted hostname
- pythonorg: untrusted hostname
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/701604688e40cf9d.
Report an issue: GitHub.
Appendix: source
Thrown at providers/jobvite.mjs:108
// 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 aac998c7ed)