santifer/career-ops · error
avature: cannot resolve origin for
Error message
avature: cannot resolve origin for ${entry.name} What it means
The Avature provider's fetch() calls resolveConfig(entry); when it returns null the provider cannot determine which Avature origin/instance to query, so it throws. Avature boards are self-hosted per customer, so the entry must supply enough info (an api URL or a recognizable origin) to build the search endpoint.
Solutions
- Add the entry's explicit `api:` URL pointing at the company's Avature endpoint (their real Avature search URL).
- Discover the actual Avature endpoint by inspecting network requests on the company's careers page and copy the search API URL into the config.
- If the company is not on Avature anymore, reassign the entry to the correct provider.
- Fail fast at config validation: run resolveConfig over all entries up front and report which ones cannot resolve.
Example fix
// before
{ name: 'ExampleCo', careers_url: 'https://exampleco.com/jobs' }
// fetch throws: cannot resolve origin
// after
{ name: 'ExampleCo', api: 'https://exampleco.avature.net/api/search' } Defensive patterns
Strategy: fallback
Validate before calling
function hasAvatureOrigin(entry) {
return resolveConfig(entry) != null;
} Type guard
function isAvatureReadyEntry(entry) {
const cfg = entry ? resolveConfig(entry) : null;
return cfg != null && typeof cfg.origin === 'string' && cfg.origin.startsWith('https://');
} Try / catch
try {
return await avatureProvider.fetch(entry, ctx);
} catch (err) {
if (/cannot resolve origin/.test(err.message)) {
console.warn(`Entry ${entry.name}: add an explicit Avature api URL to portals.yml`);
return null;
}
throw err;
} Prevention
- Capture the real Avature search endpoint from the board's network requests before configuring the entry.
- Re-verify origins after companies change ATS vendors.
- Run a startup pass that resolves config for every Avature entry and reports failures.
- Keep provider types consistent — don't reuse Greenhouse-shaped entries for Avature boards.
When it happens
Trigger: Calling fetch(entry) with an entry that has no `api` URL and no URL resolveConfig can map to an Avature origin — e.g. only a generic careers page, or an api URL on a domain resolveConfig does not recognize.
Common situations: portals.yml entry listing a company's own careers site with a note 'powered by Avature' but no API endpoint; tenant URL changed after a company migrated; config copied from another provider type.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- arbeitnow: invalid URL
- arbeitsagentur: entry
- ashby: cannot derive API URL for
- bamboohr: cannot derive API URL for
- beesite: cannot resolve search host for
AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16).
Data as JSON: /api/errors/d6e36be653224ac1.
Report an issue: GitHub.
Appendix: source
Thrown at providers/avature.mjs:185
/** @type {Provider} */
export default {
id: 'avature',
detect(entry) {
const url = entry.api || entry.careers_url || '';
if (typeof url !== 'string') return null;
try {
const host = new URL(url).host.toLowerCase();
if (host === 'avature.net' || host.endsWith('.avature.net')) return { url };
} catch {
/* not absolute */
}
return null;
},
async fetch(entry, ctx) {
const cfg = resolveConfig(entry);
if (!cfg) throw new Error(`avature: cannot resolve origin for ${entry.name}`);
const maxPages = Math.min(
HARD_MAX_PAGES,
Number.isFinite(entry.max_pages) && entry.max_pages > 0 ? Number(entry.max_pages) : DEFAULT_MAX_PAGES,
);
// Pagination key. An explicit `offset_param` pins it (and disables the
// auto-switch below); otherwise start with `jobOffset` and self-heal. A
// non-string/empty override falls back to the default so a malformed entry
// can't produce `?=N`.
const pinned = typeof entry.offset_param === 'string' && entry.offset_param.trim();
let offsetParam = pinned ? entry.offset_param.trim() : PRIMARY_OFFSET_PARAM;
let canHeal = !pinned; // once the key is pinned, never auto-switch
const jobs = [];
const seen = new Set();
const getPage = async (param, page) => {
const usp = new URLSearchParams(cfg.extraParams);View on GitHub (pinned to e7abd431fc)