santifer/career-ops · error · Error

radancy: cannot resolve search-jobs URL for

Error message

radancy: cannot resolve search-jobs URL for ${entry.name}

What it means

The radancy provider requires an explicitly configured Radancy search-jobs URL (it deliberately performs no auto-detection). resolveListUrl() returned null — no valid search-jobs URL could be derived from the entry — so fetch() aborts instead of guessing.

Solutions

  1. Add or correct the careers_url so it points at the Radancy search-jobs page (e.g. https://<tenant>.<region>/search-jobs)
  2. Confirm the entry declares provider: radancy and that its URL is a genuine Radancy-hosted board
  3. Parse-test the URL (new URL(raw) must succeed and use https:)
  4. If the company is not on Radancy, remove the provider override or switch to the correct provider

Example fix

// before (portals.yml)
- name: Acme
  provider: radancy
// after
- name: Acme
  provider: radancy
  careers_url: https://acme.aon.help/search-jobs
Defensive patterns

Strategy: validation

Validate before calling

function hasRadancySearchUrl(entry) {
  const raw = typeof entry.careers_url === 'string' ? entry.careers_url : '';
  if (!raw) return false;
  try { const u = new URL(raw); return u.protocol === 'https:' && /search-jobs|jobs|search/i.test(u.pathname); }
  catch { return false; }
}

Type guard

function isRadancyEntry(entry) {
  return entry?.provider === 'radancy' && typeof entry?.careers_url === 'string' && entry.careers_url.length > 0;
}

Try / catch

try {
  await radancy.fetch(entry, ctx);
} catch (err) {
  if (err.message.includes('cannot resolve search-jobs URL')) {
    console.warn(`Radancy entry ${entry.name} missing a valid search-jobs careers_url — skipping`);
    return [];
  }
  throw err;
}

Prevention

When it happens

Trigger: fetch() invoked for an entry with no careers_url/search URL configured, or a URL that does not resolve to a Radancy search-jobs endpoint per the provider's resolver rules.

Common situations: An entry tagged `provider: radancy` in portals.yml lacks the careers_url field; the configured URL points at a company landing page rather than the Radancy jobs search path; a typo prevents URL parsing.

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


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/8f0c7e4b4ca6fb68. Report an issue: GitHub.

Appendix: source

Thrown at providers/radancy.mjs:312

export function resolveMaxJobs(entry) {
  const v = entry?.max_jobs;
  if (Number.isInteger(v) && v > 0) return Math.min(v, MAX_JOBS_CAP);
  return DEFAULT_MAX_JOBS;
}

/** @type {Provider} */
export default {
  id: 'radancy',

  detect() {
    // Branded hosts carry no stable Radancy token in the URL — wire explicitly
    // with `provider: radancy`. No auto-detection.
    return null;
  },

  async fetch(entry, ctx) {
    const listUrl = resolveListUrl(entry);
    if (!listUrl) throw new Error(`radancy: cannot resolve search-jobs URL for ${entry.name}`);
    const origin = new URL(listUrl).origin;

    const wait = (ms) => (ctx.sleep ? ctx.sleep(ms) : new Promise((r) => setTimeout(r, ms)));
    const maxPages = resolveMaxPages(entry);
    const maxJobs = resolveMaxJobs(entry);
    // ctx.maxPages is set only by verify-portals.mjs's bounded liveness probe
    // (never during a real scan). While probing: cap the walk to that budget
    // (SHOULD — reference providers/workday.mjs) so a healthy large board
    // doesn't burn the probe's whole request allotment on one tenant, and
    // propagate any ctx.fetch* rejection unwrapped instead of absorbing it
    // into the normal partial-result handling (MUST). verify-portals
    // identifies its own budget-exhaustion sentinel, ProbePageBudgetReached,
    // by `instanceof`, and reads it as "endpoint live, count unknown"; a
    // per-page catch that swallows it into a normal stopReason/break instead
    // misreports a healthy board as broken. Reference: providers/vdab.mjs.
    const probing = Number.isInteger(ctx?.maxPages) && ctx.maxPages > 0;
    const effectiveMaxPages = probing ? Math.min(maxPages, ctx.maxPages) : maxPages;
    const jobs = [];

View on GitHub (pinned to aac998c7ed)