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 toView on GitHub (pinned to 9b17a8ac97)
Solutions
- Add a non-empty careers_url string to the entry, ideally the https://<slug>.jibeapply.com form.
- 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.
- 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
- Always supply a non-empty careers_url string for provider: jibeapply, even when driving via entry.api.
- Lint portal entries to flag any provider: jibeapply row missing careers_url.
- Remember the explicit-provider path bypasses detect()'s guard, so fetch()'s check is the only gate.
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
- jibeapply: cannot derive API URL for ${entry.name}
- breezy: cannot derive API URL for ${entry.name}
- comeet: cannot derive API URL for ${entry.name} (set api: to
- consider: ${entry.name} needs an https careers_url on a publ
- csod: cannot resolve careersite URL for ${entry.name}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/407618a0f1e53401.
Report an issue: GitHub.