santifer/career-ops · error · Error
justjoin: URL path must be /job-offers or /api/candidate-api
Error message
justjoin: URL path must be /job-offers or /api/candidate-api/offers: ${url} What it means
Thrown by assertJustJoinUrl() when the URL is valid HTTPS on justjoin.it but the pathname is neither /job-offers (or a prefix of it) nor the exact /api/candidate-api/offers endpoint. The provider restricts fetchable paths to the two known justjoin.it routes so a tampered URL cannot reach an arbitrary path on the host.
Source
Thrown at providers/justjoin.mjs:26
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;
}
}
function normalizeLocation(offer) {
const parts = [];
const workplace = String(offer?.workplaceType || '').trim();View on GitHub (pinned to 9b17a8ac97)
Solutions
- For the api field, use https://justjoin.it/api/candidate-api/offers (or omit it — buildApiUrl defaults to API_BASE).
- For careers_url, use a https://justjoin.it/job-offers/... URL.
- If justjoin.it renamed the endpoint, update API_BASE and the path allow-check in providers/justjoin.mjs.
Example fix
# before — stale endpoint acme: provider: justjoin api: https://justjoin.it/api/v1/offers # after — current endpoint acme: provider: justjoin api: https://justjoin.it/api/candidate-api/offers
Defensive patterns
Strategy: validation
Validate before calling
function isAllowedJustJoinPath(url) {
try {
const p = new URL(url);
return p.pathname.startsWith('/job-offers') || p.pathname === '/api/candidate-api/offers';
} catch { return false; }
} Type guard
/** @param {string} url @returns {boolean} */
function isJustJoinApiUrl(url) {
try {
const p = new URL(url);
return p.protocol === 'https:' && p.hostname === 'justjoin.it'
&& (p.pathname.startsWith('/job-offers') || p.pathname === '/api/candidate-api/offers');
} catch { return false; }
} Prevention
- Prefer omitting api and letting buildApiUrl default to API_BASE to avoid stale endpoints.
- Track justjoin.it API version changes in a changelog and update API_BASE promptly.
- Lint api fields against the allowed-path set.
When it happens
Trigger: An api URL pointing at a different justjoin.it endpoint (e.g. an old /api/v1/... path); a careers_url whose path is neither /job-offers nor the API; a typo or stale endpoint from a prior justjoin.it API version.
Common situations: justjoin.it changed its API path (version bump); the user configured a careers_url to the company landing page rather than /job-offers; an old endpoint was retired.
Related errors
- justjoin: invalid URL: ${url}
- justjoin: URL must use HTTPS: ${url}
- arbeitnow: invalid URL: ${url}
- ashby: invalid URL: ${url}
- bamboohr: invalid URL: ${url}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/4874b61f3b9be7ff.
Report an issue: GitHub.