santifer/career-ops · error · Error
successfactors: cannot resolve origin for ${entry.name}
Error message
successfactors: cannot resolve origin for ${entry.name} What it means
resolveConfig parses entry.api or entry.careers_url and derives the RMK/CSB endpoint origins; it returns null only if new URL throws or the protocol is not http/https. fetch throws when that happens. Note detect() matches on a loose regex (successfactors.(eu|com)|jobs2web.com) against the raw string, so a string can pass detection yet fail URL parsing — and a provider: successfactors override skips detection entirely.
Source
Thrown at providers/successfactors.mjs:417
startrow += tiles.length;
}
// The cap is checked between pages, so the last page can overshoot it.
return jobs.slice(0, MAX_JOBS);
}
/** @type {Provider} */
export default {
id: 'successfactors',
detect(entry) {
const url = entry.api || entry.careers_url || '';
if (/successfactors\.(eu|com)|jobs2web\.com/i.test(url)) return { url };
return null;
},
async fetch(entry, ctx) {
const cfg = resolveConfig(entry);
if (!cfg) throw new Error(`successfactors: cannot resolve origin for ${entry.name}`);
// Explicit opt-in goes straight to CSB. RMK tenants (the majority) run the
// tile scraper; only when it comes back empty — the CSB empty-shell
// signature — do we auto-fall back to the JSON API, so an unflagged CSB
// tenant still works and a genuinely-empty RMK board costs one extra probe.
if (String(entry.sfVariant || '').toLowerCase() === 'csb') {
return fetchCsb(entry, cfg, ctx);
}
const rmkJobs = await fetchRmk(entry, cfg, ctx);
if (rmkJobs.length > 0) return rmkJobs;
// RMK answered (healthy, possibly legitimately empty) — the CSB call here
// is only a probe for the empty-shell signature, so it must not turn a
// failing/absent CSB endpoint into a dead-board throw.
return fetchCsb(entry, cfg, ctx, { probe: true });
},
};
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Provide a full absolute URL with scheme: https://careers.example.com or https://<tenant>.successfactors.com
- Ensure the protocol is http or https (https strongly preferred)
- If using provider: successfactors as an override, also set careers_url or api to the valid tenant URL
- Verify the URL still resolves in a browser — a decommissioned tenant origin can also yield odd responses upstream
Example fix
# before - name: Acme provider: successfactors careers_url: successfactors.com/acme/careers # after - name: Acme provider: successfactors careers_url: https://acme.successfactors.com/careers
Defensive patterns
Strategy: validation
Validate before calling
// Validate the entry URL is parseable http(s) before successfactors.fetch.
function resolvableOrigin(v) {
try {
const u = new URL(v);
return u.protocol === 'http:' || u.protocol === 'https:';
} catch { return false; }
}
if (!resolvableOrigin(entry.api || entry.careers_url)) {
console.warn(`${entry.name}: successfactors needs a valid http(s) URL`);
} Prevention
- Always include the https:// scheme; detect's regex can match a scheme-less string that URL() then rejects.
- When setting provider: successfactors as an override, also set a valid api/careers_url.
- Lint entries whose URL string matches the detect regex but fails new URL().
When it happens
Trigger: The entry string contains 'successfactors.com' (so detect's regex matches) but is not a valid absolute URL, e.g. 'successfactors.com/careers' with no scheme. Or provider: successfactors is set but api/careers_url is missing or malformed. A protocol like ftp:// would also fail the http/https gate.
Common situations: A manually-added entry omits the https:// scheme; YAML mis-parsing produced a non-string; or provider: successfactors was force-set on an entry that has no usable URL.
Related errors
- softgarden: cannot resolve widget URL for ${entry.name}
- tkms: cannot resolve jobs host for ${entry.name}
- glints: invalid URL: ${url}
- glints: URL must use HTTPS: ${url}
- greenhouse: invalid URL: ${url}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/56f40d550a5a8a04.
Report an issue: GitHub.