santifer/career-ops · error
comeet: invalid URL
Error message
comeet: invalid URL: ${redactToken(url)} What it means
assertComeetUrl validates that a URL is a syntactically valid Comeet careers-api URL before the provider fetches it. The first check is parseability: new URL(url) throws for malformed strings, and assertComeetUrl converts that into a labeled error (with the per-tenant ?token= redacted) so failures are attributable to the right portal entry.
Solutions
- Inspect the entry's api/careers_url value in portals.yml and fix the malformed URL string
- Ensure the URL includes the scheme: https://www.comeet.co/careers-api/2.0/company/<uid>/positions?token=<token>
- Trim whitespace/quotes when loading the config (the provider only trims in the collage provider; comeet's isComeetApiUrl rejects whitespace-padded strings)
- Validate with new URL(url) locally before committing the config
Example fix
// before (portals.yml) - name: Acme provider: comeet api: www.comeet.co/careers-api/2.0/company/acme/positions?token=abc // after - name: Acme provider: comeet api: https://www.comeet.co/careers-api/2.0/company/acme/positions?token=abc
Defensive patterns
Strategy: validation
Validate before calling
function isParseableUrl(raw) {
if (typeof raw !== 'string' || !raw.trim()) return false;
try { new URL(raw.trim()); return true; } catch { return false; }
}
if (!isParseableUrl(entry.api)) throw new Error(`entry ${entry.name}: api is not a valid URL`); Type guard
function isUrlString(raw) {
if (typeof raw !== 'string') return false;
try { new URL(raw); return true; } catch { return false; }
} Try / catch
try {
const url = assertComeetUrl(entry.api);
} catch (err) {
if (String(err.message).includes('invalid URL')) {
logger.error({entry: entry.name}, 'comeet api value is not a parseable URL — check scheme, quotes, whitespace');
} else throw err;
} Prevention
- Always include the https:// scheme when pasting Comeet API URLs into portals.yml
- Trim copied URLs; watch for hidden whitespace/newlines and YAML quoting artifacts
- Validate the whole portals.yml with a URL-schema check in CI before running scans
- Use the token-redacted error message as-is; don't re-log the raw URL (it carries a secret)
When it happens
Trigger: resolveApiUrl passed a value that failed the isComeetApiUrl guard for a non-format reason — practically, fetch() receives an entry whose api/careers_url is a malformed string (missing scheme, spaces, unescaped characters) that somehow bypassed the typeof/URL pre-checks, or assertComeetUrl is called directly with user input that isn't a URL.
Common situations: Pasting a Comeet careers page URL with a typo (missing 'https://', stray space or newline copied from a document); storing the URL with surrounding quotes in YAML; hand-editing portals.yml and breaking the URL.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- arbeitnow: invalid URL
- 4dayweek: invalid URL
- 4dayweek: 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/a2f04d3f19776134.
Report an issue: GitHub.
Appendix: source
Thrown at providers/comeet.mjs:34
/** @param {unknown} raw */
function isComeetApiUrl(raw) {
if (typeof raw !== 'string' || !raw) return false;
let parsed;
try {
parsed = new URL(raw);
} catch {
return false;
}
return parsed.protocol === 'https:' && parsed.hostname === COMEET_API_HOST && parsed.pathname.startsWith('/careers-api/');
}
/** @param {string} url */
function assertComeetUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`comeet: invalid URL: ${redactToken(url)}`);
}
if (parsed.protocol !== 'https:') throw new Error(`comeet: URL must use HTTPS: ${redactToken(url)}`);
if (parsed.hostname !== COMEET_API_HOST)
throw new Error(`comeet: untrusted hostname "${parsed.hostname}" — must be ${COMEET_API_HOST}`);
if (!parsed.pathname.startsWith('/careers-api/'))
throw new Error(`comeet: URL path must be the careers-api endpoint: ${redactToken(url)}`);
return url;
}
// Redact the per-tenant ?token= so neither the (informational, possibly-logged)
// DetectHit url nor a thrown validation error carries the secret. Best-effort:
// falls back to a regex strip when the value can't be parsed as a URL.
function redactToken(url) {
try {
const parsed = new URL(url);
if (parsed.searchParams.has('token')) parsed.searchParams.set('token', 'REDACTED');
return parsed.href;
} catch {View on GitHub (pinned to aac998c7ed)