santifer/career-ops · error · Error

jibeapply: careers_url required

Error message

jibeapply: careers_url required

What it means

Thrown by jibeapply fetch() when entry.careers_url is not a non-empty string. careers_url is the one field the JibeApply provider unconditionally requires (detect() also returns null without it). fetch() checks this before attempting any URL derivation, so a missing/blank/non-string careers_url fails fast with a clear message rather than a downstream null deref.

Source

Thrown at providers/jibeapply.mjs:92

    })
    .filter(Boolean);
}

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

  detect(entry) {
    const url = entry.careers_url;
    if (typeof url !== 'string') return null;
    const apiUrl = toApiUrl(url);
    if (!apiUrl) return null;
    return { url: apiUrl };
  },

  async fetch(entry, ctx) {
    const url = entry.careers_url;
    if (typeof url !== 'string' || !url) throw new Error('jibeapply: careers_url required');

    // Prefer an explicit entry.api (allows iCIMS-hosted, branded JibeApply sites
    // that share the same JSON schema but aren't on jibeapply.com).
    const apiUrl = (typeof entry.api === 'string' && validateExplicitApi(entry.api))
      || toApiUrl(url);
    if (!apiUrl) throw new Error(`jibeapply: cannot derive API URL for ${entry.name}`);
    const first = await ctx.fetchJson(apiUrl, { redirect: 'error' });
    const total = first.totalCount ?? 0;
    // Use the actual number of items returned as page size — some implementations
    // set `count` to the total rather than the per-page count.
    const pageSize = first.jobs?.length || first.count || DEFAULT_PAGE_SIZE;
    const allJobs = [...(first.jobs ?? [])];

    if (total > pageSize && pageSize > 0) {
      const maxPages = resolveMaxPages(entry);
      const pages = Math.min(Math.ceil(total / pageSize), maxPages);
      // Sequential, not concurrent (mirrors providers/4dayweek.mjs, thehub.mjs,
      // arbeitnow.mjs, workday.mjs) — a single tenant's API has no reason to

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Add a non-empty careers_url string to the entry, ideally the https://<slug>.jibeapply.com form.
  2. If you intended to drive JibeApply purely via entry.api (iCIMS-hosted branded site), note that fetch() still requires careers_url to be a non-empty string — supply it even if api is the real source.
  3. Validate entries before scan: assert every provider: jibeapply row has a string careers_url.

Example fix

# before
- name: Acme
  provider: jibeapply
  api: https://careers.acme.com/api/jobs

# after
- name: Acme
  provider: jibeapply
  careers_url: https://acme.jibeapply.com
  api: https://careers.acme.com/api/jobs
Defensive patterns

Strategy: validation

Validate before calling

// Enforce the required field before driving the provider.
if (typeof entry.careers_url !== 'string' || !entry.careers_url) {
  throw new Error(`jibeapply: ${entry.name} is missing the required careers_url string`);
}

Type guard

/** Entry has the non-empty string careers_url the JibeApply provider requires. */
function hasJibeapplyCareersUrl(entry) {
  return !!entry && typeof entry === 'object'
    && typeof entry.careers_url === 'string' && entry.careers_url.length > 0;
}

Try / catch

try {
  const jobs = await jibeapplyProvider.fetch(entry, ctx);
} catch (err) {
  if (/careers_url required/.test(err.message)) {
    console.error(`config: ${entry.name} — jibeapply needs a non-empty careers_url string`);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: An entry explicitly tagged provider: jibeapply but with no careers_url key, an empty careers_url: '', or careers_url set to a non-string YAML value (number/bool). The provider was routed explicitly (bypassing detect) but the required field was omitted.

Common situations: Setting provider: jibeapply without supplying careers_url (the explicit-provider path skips detect's guard); YAML indentation putting careers_url under a nested block so it is undefined at the entry level; a templating step that blanked the field.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/407618a0f1e53401. Report an issue: GitHub.