santifer/career-ops · error · Error
justjoin: untrusted hostname "${parsed.hostname}" — must be
Error message
justjoin: untrusted hostname "${parsed.hostname}" — must be justjoin.it What it means
Thrown by assertJustJoinUrl() when the parsed URL's hostname is not exactly 'justjoin.it' (the sole entry in ALLOWED_HOSTS). The provider refuses to fetch any other host to prevent SSRF via redirect or a tampered entry pointing at an internal/attacker server. Note www.justjoin.it or any subdomain is also rejected since the set is a strict exact match.
Source
Thrown at providers/justjoin.mjs:23
// Browser URLs under https://justjoin.it/job-offers/... are accepted for
// detection, but fetches use https://justjoin.it/api/candidate-api/offers.
const ALLOWED_HOSTS = new Set(['justjoin.it']);
const API_BASE = 'https://justjoin.it/api/candidate-api/offers';
const JOB_BASE = 'https://justjoin.it/job-offer/';
const PAGE_SIZE = 100;
const MAX_PAGES = 50;
function assertJustJoinUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`justjoin: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`justjoin: URL must use HTTPS: ${url}`);
if (!ALLOWED_HOSTS.has(parsed.hostname)) {
throw new Error(`justjoin: untrusted hostname "${parsed.hostname}" — must be justjoin.it`);
}
if (!parsed.pathname.startsWith('/job-offers') && parsed.pathname !== '/api/candidate-api/offers') {
throw new Error(`justjoin: URL path must be /job-offers or /api/candidate-api/offers: ${url}`);
}
return parsed;
}
function detectUrl(entry) {
const url = entry.api || entry.careers_url || '';
if (typeof url !== 'string' || !url.trim()) return null;
try {
const parsed = assertJustJoinUrl(url);
return { url: parsed.href };
} catch {
return null;
}
}
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Use the canonical host justjoin.it (drop any www or subdomain prefix).
- If the company is not on justjoin.it, switch the entry's provider to the correct ATS.
- Confirm the URL is https://justjoin.it/... with no subdomain.
Example fix
# before acme: provider: justjoin api: https://www.justjoin.it/api/candidate-api/offers # after acme: provider: justjoin api: https://justjoin.it/api/candidate-api/offers
Defensive patterns
Strategy: validation
Validate before calling
function isTrustedJustJoinHost(url) {
try { return new URL(url).hostname === 'justjoin.it'; } catch { return false; }
} Type guard
/** @param {string} url @returns {boolean} */
function isJustJoinHttpsUrl(url) {
try {
const p = new URL(url);
return p.protocol === 'https:' && p.hostname === 'justjoin.it';
} catch { return false; }
} Prevention
- Use the exact host justjoin.it — no www or subdomain.
- If a company is not on justjoin.it, do not use the justjoin provider.
- Lint entries against the provider's trusted-host set.
When it happens
Trigger: An api/careers_url pointing at a different domain (www.justjoin.it, an API proxy, an internal IP); a CNAME or vanity domain that isn't in the allow-list; an attempt to use the justjoin provider for a non-justjoin board.
Common situations: A www-prefixed URL that the user assumed was equivalent; pointing the provider at a proxy or mirror; wrong provider selected for a board.
Related errors
- jobvite: untrusted hostname "${parsed.hostname}" — must be $
- justjoin: invalid URL: ${url}
- justjoin: URL must use HTTPS: ${url}
- landingjobs: untrusted hostname "${parsed.hostname}" — must
- flowxtra: untrusted hostname "${parsed.hostname}" — must be
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/902e859b882770fb.
Report an issue: GitHub.