santifer/career-ops · error · Error
justjoin: untrusted hostname
Error message
justjoin: untrusted hostname "${parsed.hostname}" — must be justjoin.it What it means
Thrown by assertJustJoinUrl when the URL's hostname is not in the allow-list, which contains only 'justjoin.it'. The provider is a purpose-built scanner for one ATS, so it rejects any other host to prevent SSRF-style misuse or accidentally hitting a lookalike/mirror domain. Even a valid HTTPS URL to another job board is refused here.
Solutions
- Set careers_url/api to a hostname of exactly 'justjoin.it' — drop 'www.' and any suffix
- If you meant another job board, use that board's provider instead of justjoin
- Strip redirect/shortener wrappers and use the canonical justjoin.it URL
Example fix
// before (portals.yml) api: https://www.justjoin.it/api/candidate-api/offers // after api: https://justjoin.it/api/candidate-api/offers
Defensive patterns
Strategy: validation
Validate before calling
function isTrustedJustJoinUrl(url) {
try { return new URL(url).hostname === 'justjoin.it'; } catch { return false; }
}
if (!isTrustedJustJoinUrl(entry.careers_url || entry.api || '')) throw new Error('host must be justjoin.it'); Type guard
const isJustJoinHost = (u) => { try { return new URL(u).hostname === 'justjoin.it'; } catch { return false; } }; Try / catch
try {
await provider.fetch(entry, ctx);
} catch (e) {
if (e.message.includes('untrusted hostname')) {
console.error(`justjoin provider got a non-justjoin.it host: ${e.message}`);
} else throw e;
} Prevention
- Use the bare hostname justjoin.it — never www., subdomains, or mirror domains
- Run provider.detect(entry) before fetch and treat null as 'wrong provider', not a soft failure
- Strip shortener/redirect-tracked links down to their canonical destination before configuring
When it happens
Trigger: entry.api or entry.careers_url points at a hostname other than justjoin.it — e.g. 'https://justjoin.it.evil.example.com/api/candidate-api/offers', 'https://www.justjoin.it/...' (www subdomain), 'https://nofluffjobs.com/...'. Triggered via assertJustJoinUrl through buildApiUrl during fetch, or surfaced indirectly when detect() silently returns null and fetch() raises error 319.
Common situations: Copy-pasting a URL with a 'www.' prefix; typo-squat or redirect-tracked URLs (utm-wrapped links through a shortener host); configuring this provider against a different job board by mistake; a regional mirror domain.
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
- arbeitnow: untrusted hostname
- arbeitnow: URL must use HTTPS
- ashby: untrusted hostname
- bamboohr: untrusted hostname
- breezy: untrusted hostname
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/902e859b882770fb.
Report an issue: GitHub.
Appendix: 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 aac998c7ed)