santifer/career-ops · error
ashby: URL must use HTTPS
Error message
ashby: URL must use HTTPS: ${url} What it means
After a URL parses successfully, assertAshbyUrl rejects any URL whose protocol is not https. The Ashby provider deliberately forbids http:// (and any other scheme) so credentials and board data are never sent over plaintext and no downgrade redirect tricks are possible.
Solutions
- Change the URL scheme to `https://` in the portals.yml entry or calling code.
- If the target only serves http, it is unsupported — find the canonical HTTPS Ashby board URL (`https://jobs.ashby.co/<org>` or the `jobs.ashbyhq.com` endpoint).
- Pre-normalize inputs: `if (url.startsWith('http://')) url = 'https://' + url.slice(7)` only when you control the source and know HTTPS is served.
- Check for double-scheme mistakes like `https://http://...` produced by concatenation.
Example fix
// before
assertAshbyUrl('http://jobs.ashby.co/exampleco'); // throws
// after
assertAshbyUrl('https://jobs.ashby.co/exampleco'); // ok Defensive patterns
Strategy: validation
Validate before calling
function isHttpsUrl(url) {
try { return new URL(url).protocol === 'https:'; } catch { return false; }
} Type guard
function asHttpsUrl(value) {
const u = new URL(value); // caller ensures parseable
return u.protocol === 'https:' ? u : null;
} Try / catch
try {
assertAshbyUrl(url);
} catch (err) {
if (/must use HTTPS/.test(err.message)) {
url = url.replace(/^http:/, 'https:');
assertAshbyUrl(url);
} else throw err;
} Prevention
- Always use https:// in job-board config; all major ATS hosts serve HTTPS.
- Normalize http:// to https:// at config load for known ATS hosts.
- Watch for string concatenation that drops or mangles the scheme.
- Add an https-only check to your config lint.
When it happens
Trigger: Calling assertAshbyUrl with a parsed-valid URL using `http://` (e.g. `http://jobs.ashby.co/...`), or any other scheme like `ftp://` or a custom scheme that still parses.
Common situations: Old or hand-copied config entries pointing at plain http, internal proxy-style URLs like `http://localhost:8080`, or a config where the scheme got stripped/mangled by a YAML parser or string templating.
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: URL must use HTTPS
- ashby: untrusted hostname
- bamboohr: URL must use HTTPS
- breezy: URL must use HTTPS
- builtin: URL must use HTTPS
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/0023ca7b811f9fe6.
Report an issue: GitHub.
Appendix: source
Thrown at providers/ashby.mjs:91
const resolvedMax = /** @type {number} */ (max ?? min);
return {
min: Math.min(resolvedMin, resolvedMax),
max: Math.max(resolvedMin, resolvedMax),
currency: currency.toUpperCase(),
};
}
const ALLOWED_ASHBY_HOSTS = new Set(['api.ashbyhq.com']);
/** @param {string} url */
function assertAshbyUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`ashby: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`ashby: URL must use HTTPS: ${url}`);
if (!ALLOWED_ASHBY_HOSTS.has(parsed.hostname))
throw new Error(`ashby: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_ASHBY_HOSTS].join(', ')}`);
return url;
}
/** @param {import('./_types.js').PortalEntry} entry */
function resolveApiUrl(entry) {
// Explicit api: wins — lets an entry keep a human-facing corporate
// careers_url (e.g. https://openai.com/careers) while still pinning the
// Ashby posting-api board (mirrors greenhouse's api: precedence).
if (entry.api) {
assertAshbyUrl(entry.api);
return entry.api;
}
const url = entry.careers_url || '';
const match = url.match(/jobs\.ashbyhq\.com\/([^/?#]+)/);
if (!match) return null;
return `https://api.ashbyhq.com/posting-api/job-board/${match[1]}?includeCompensation=true`;View on GitHub (pinned to aac998c7ed)