{"record":{"id":"56f40d550a5a8a04","repo":"santifer/career-ops","slug":"successfactors-cannot-resolve-origin-for-entry","errorCode":null,"errorMessage":"successfactors: cannot resolve origin for ${entry.name}","messagePattern":"successfactors: cannot resolve origin for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/successfactors.mjs","lineNumber":417,"sourceCode":"    startrow += tiles.length;\n  }\n  // The cap is checked between pages, so the last page can overshoot it.\n  return jobs.slice(0, MAX_JOBS);\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'successfactors',\n\n  detect(entry) {\n    const url = entry.api || entry.careers_url || '';\n    if (/successfactors\\.(eu|com)|jobs2web\\.com/i.test(url)) return { url };\n    return null;\n  },\n\n  async fetch(entry, ctx) {\n    const cfg = resolveConfig(entry);\n    if (!cfg) throw new Error(`successfactors: cannot resolve origin for ${entry.name}`);\n\n    // Explicit opt-in goes straight to CSB. RMK tenants (the majority) run the\n    // tile scraper; only when it comes back empty — the CSB empty-shell\n    // signature — do we auto-fall back to the JSON API, so an unflagged CSB\n    // tenant still works and a genuinely-empty RMK board costs one extra probe.\n    if (String(entry.sfVariant || '').toLowerCase() === 'csb') {\n      return fetchCsb(entry, cfg, ctx);\n    }\n    const rmkJobs = await fetchRmk(entry, cfg, ctx);\n    if (rmkJobs.length > 0) return rmkJobs;\n    // RMK answered (healthy, possibly legitimately empty) — the CSB call here\n    // is only a probe for the empty-shell signature, so it must not turn a\n    // failing/absent CSB endpoint into a dead-board throw.\n    return fetchCsb(entry, cfg, ctx, { probe: true });\n  },\n};\n","sourceCodeStart":399,"sourceCodeEnd":434,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/successfactors.mjs#L399-L434","documentation":"The successfactors provider must resolve each entry to a concrete tenant origin/config via resolveConfig(entry). When the entry's URL matches no known SuccessFactors pattern and no explicit origin is configured, it throws with the entry's name. This is a fail-fast for entries the provider genuinely cannot talk to.","triggerScenarios":"A portals.yml entry has provider: successfactors but its careers_url matches neither successfactors.eu/com nor jobs2web.com patterns, or lacks the URL fields resolveConfig expects; entry.sfVariant/origin hints are missing for a tenant needing them.","commonSituations":"A company migrated off SuccessFactors so the URL no longer matches; someone pointed the successfactors provider at a generic careers page; a custom vanity domain not covered by the regexes was configured without explicit config.","solutions":["Set an explicit origin/sfVariant (e.g. sfVariant: csb) in the entry so resolveConfig succeeds","Point careers_url at the actual SuccessFactors tenant URL (careers.xx.successfactors.eu or *.jobs2web.com)","Confirm the company still uses SuccessFactors; if it moved to another ATS, switch the entry's provider","Check resolveConfig's accepted patterns in providers/successfactors.mjs and align the URL"],"exampleFix":"// before\n- name: Acme\n  provider: successfactors\n  careers_url: 'https://acme.com/careers'\n// after\n- name: Acme\n  provider: successfactors\n  careers_url: 'https://acme.successfactors.eu/careers'\n  # or: sfVariant: csb","handlingStrategy":"validation","validationCode":"const SF_RE = /(successfactors\\.(eu|com)|jobs2web\\.com)/i;\nif (String(entry.provider) === 'successfactors' && !(entry.careers_url && SF_RE.test(entry.careers_url))) {\n  throw new Error(`${entry.name}: successfactors needs a careers_url on a successfactors.eu/com or jobs2web.com host (or explicit sfVariant/origin)`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  offers = await provider.fetch(entry, ctx);\n} catch (e) {\n  if (e.message.startsWith('successfactors: cannot resolve origin')) {\n    console.warn(`${entry.name}: provider cannot map URL to an SF tenant — fix entry config`);\n    return [];\n  }\n  throw e;\n}","preventionTips":["Point entries at the real SF tenant URL (careers.*.successfactors.eu or *.jobs2web.com)","Set sfVariant: csb explicitly for CSB tenants","Re-verify entries when a company announces an ATS migration","Run audit-portals.mjs after adding companies"],"tags":["config","url-validation","ats"],"backgroundTag":"missing-required-config-field","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}