santifer/career-ops · error · Error
justjoin: URL must use HTTPS
Error message
justjoin: URL must use HTTPS: ${url} What it means
This error is thrown by assertJustJoinUrl in providers/justjoin.mjs when a configured justjoin.it URL uses a protocol other than https:. The provider only accepts HTTPS because it talks to justjoin.it's candidate API with credentials-free requests and forbids downgrade/redirect tricks (fetch uses redirect: 'error'). It is an input-validation guard on portals.yml entries before any network call is made.
Solutions
- Change the URL in portals.yml (careers_url or api) to use https:// — e.g. https://justjoin.it/api/candidate-api/offers
- If the URL comes from an env var or script, normalize it before passing: ensure it starts with 'https://'
- Verify with `new URL(url).protocol === 'https:'` before calling the provider's detect/fetch
Example fix
// before (portals.yml) careers_url: http://justjoin.it/job-offers // after careers_url: https://justjoin.it/job-offers
Defensive patterns
Strategy: validation
Validate before calling
function isHttpsUrl(url) {
try { return new URL(url).protocol === 'https:'; } catch { return false; }
}
if (!isHttpsUrl(entry.api || entry.careers_url || '')) throw new Error('justjoin URL must be HTTPS'); Type guard
const isHttpsUrl = (u) => { try { return new URL(u).protocol === 'https:'; } catch { return false; } }; Try / catch
try {
await provider.fetch(entry, ctx);
} catch (e) {
if (e.message.startsWith('justjoin: URL must use HTTPS')) {
console.error(`Fix portals.yml entry: ${e.message}`);
} else throw e;
} Prevention
- Always write https:// in portals.yml URLs
- Add a config lint step that checks new URL(u).protocol === 'https:' for all careers_url/api values
- Never assemble provider URLs via string concatenation without validating the result
When it happens
Trigger: Passing a URL string whose parsed.protocol is 'http:' (or ftp:, etc.) to assertJustJoinUrl — directly, or indirectly via buildApiUrl on entry.api, or via detectUrl during detect()/fetch(). For example entry.api: 'http://justjoin.it/api/candidate-api/offers' in portals.yml.
Common situations: A portals.yml careers_url or api value hand-typed as http:// instead of https://; a URL copied from an old blog post or HTTP mirror; a staging/proxy URL on http; string interpolation dropping the 's' when assembling the API base.
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
- 4dayweek: URL must use HTTPS
- arbeitnow: invalid URL
- arbeitnow: URL must use HTTPS
- ashby: invalid URL
- bamboohr: invalid URL
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/bf0b7fd41d02cc3b.
Report an issue: GitHub.
Appendix: source
Thrown at providers/justjoin.mjs:21
// JustJoin.it provider — hits the current candidate offers API.
// 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)