santifer/career-ops · error
ashby: invalid URL
Error message
ashby: invalid URL: ${url} What it means
The Ashby provider validates every board URL before use. assertAshbyUrl first parses the string with the URL constructor; if parsing fails (malformed URL, empty string, whitespace, missing scheme), it throws this error. It is the first gate in a chain of checks (parseability, HTTPS, hostname allowlist).
Solutions
- Print/inspect the exact offending URL value; check for missing `https://` scheme, stray whitespace, or unexpanded placeholders.
- Trim and normalize the input: `url.trim()` and prepend `https://` only if an absolute host is present but no scheme.
- Fix the offending portals.yml entry so the api/careers URL is a full absolute HTTPS URL.
- If building URLs programmatically, use `new URL(path, base)` with a validated base instead of string concatenation.
Example fix
// before const url = 'jobs.ashby.co/exampleco/postings'; assertAshbyUrl(url); // throws // after const url = 'https://jobs.ashby.co/exampleco/postings'; assertAshbyUrl(url); // passes scheme check
Defensive patterns
Strategy: validation
Validate before calling
function isValidAshbyUrl(url) {
if (typeof url !== 'string' || !url.trim()) return false;
try { new URL(url.trim()); return true; } catch { return false; }
} Type guard
function isParsedUrl(value) {
try { return { ok: true, url: new URL(value) }; } catch { return { ok: false }; }
} Try / catch
try {
assertAshbyUrl(entry.api);
} catch (err) {
console.warn(`Skipping entry ${entry.name}: ${err.message}`);
return null;
} Prevention
- Store only full absolute HTTPS URLs in portals.yml — never bare hosts or relative paths.
- Trim and quote-strip values pasted into config files.
- Add a config lint step that runs `new URL()` over every entry at load time.
- Expand and check template placeholders before committing config.
When it happens
Trigger: Calling assertAshbyUrl (directly or via the provider's fetch path) with a string that `new URL()` cannot parse — e.g. `jobs.ashby.co/board` without scheme, an empty string, a URL containing stray spaces or control characters, or a portals.yml entry whose api/careers URL is malformed.
Common situations: Hand-edited portals.yml entries with typos, URLs pasted with leading/trailing whitespace or quotes, relative URLs taken from a page instead of absolute ones, or template placeholders like `${TENANT}` left unexpanded.
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: invalid URL
- bamboohr: invalid URL
- breezy: invalid URL
- builtin: invalid URL
- careerviet: invalid URL
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/b6589393512cbf0a.
Report an issue: GitHub.
Appendix: source
Thrown at providers/ashby.mjs:89
// Ensure correct ordering (min <= max)
const resolvedMin = /** @type {number} */ (min ?? max);
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\/([^/?#]+)/);View on GitHub (pinned to aac998c7ed)