{"record":{"id":"d6e36be653224ac1","repo":"santifer/career-ops","slug":"avature-cannot-resolve-origin-for-entry-name","errorCode":null,"errorMessage":"avature: cannot resolve origin for ${entry.name}","messagePattern":"avature: cannot resolve origin for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/avature.mjs","lineNumber":140,"sourceCode":"/** @type {Provider} */\nexport default {\n  id: 'avature',\n\n  detect(entry) {\n    const url = entry.api || entry.careers_url || '';\n    if (typeof url !== 'string') return null;\n    try {\n      const host = new URL(url).host.toLowerCase();\n      if (host === 'avature.net' || host.endsWith('.avature.net')) return { url };\n    } catch {\n      /* not absolute */\n    }\n    return null;\n  },\n\n  async fetch(entry, ctx) {\n    const cfg = resolveConfig(entry);\n    if (!cfg) throw new Error(`avature: cannot resolve origin for ${entry.name}`);\n    const maxPages = Math.min(\n      HARD_MAX_PAGES,\n      Number.isFinite(entry.max_pages) && entry.max_pages > 0 ? Number(entry.max_pages) : DEFAULT_MAX_PAGES,\n    );\n\n    // Pagination key. An explicit `offset_param` pins it (and disables the\n    // auto-switch below); otherwise start with `jobOffset` and self-heal. A\n    // non-string/empty override falls back to the default so a malformed entry\n    // can't produce `?=N`.\n    const pinned = typeof entry.offset_param === 'string' && entry.offset_param.trim();\n    let offsetParam = pinned ? entry.offset_param.trim() : 'jobOffset';\n    let canHeal = !pinned; // once the key is pinned, never auto-switch\n\n    const jobs = [];\n    const seen = new Set();\n    const sleep = (ms) => (typeof ctx?.sleep === 'function' ? ctx.sleep(ms) : new Promise((r) => setTimeout(r, ms)));\n\n    const getPage = async (param, page) => {","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/avature.mjs#L122-L158","documentation":"avature's `resolveConfig` returns null when neither `entry.api`/`entry.careers_url` (or whatever fields it inspects) yields an `avature.net` origin. `fetch` then throws, naming the entry. The provider can only operate against a `*.avature.net` tenant host.","triggerScenarios":"`resolveConfig(entry)` returns null — the entry has no URL whose host is `avature.net` or ends with `.avature.net`. The detect() `try`/`catch` shows non-absolute URLs are silently rejected, so a relative URL also yields null.","commonSituations":"An entry marked `provider: avature` points at a corporate careers page (Workday/Greenhouse/custom) rather than the avature tenant, or the careers_url is relative/missing.","solutions":["Set `careers_url` (or `api:`) to the full `https://<tenant>.avature.net` origin.","Double-check the host really is an Avature tenant before assigning the provider.","If the company uses a different ATS, switch the entry's `provider:` accordingly."],"exampleFix":"# before\n- name: Acme\n  provider: avature\n  careers_url: https://careers.acme.com/\n\n# after\n- name: Acme\n  provider: avature\n  careers_url: https://acme.avature.net/fp/jobs","handlingStrategy":"type-guard","validationCode":"// Pre-check that the entry resolves to an avature origin\nfunction looksLikeAvature(entry) {\n  const u = entry.api || entry.careers_url;\n  if (typeof u !== 'string') return false;\n  try {\n    const h = new URL(u).host.toLowerCase();\n    return h === 'avature.net' || h.endsWith('.avature.net');\n  } catch { return false; }\n}\nif (!looksLikeAvature(entry)) {\n  console.warn(`avature: skipping ${entry.name} — no avature.net origin in api/careers_url`);\n  continue;\n}","typeGuard":"/** @param {any} e */\nfunction hasAvatureOrigin(e) {\n  const u = e?.api ?? e?.careers_url;\n  if (typeof u !== 'string') return false;\n  try {\n    const h = new URL(u).host.toLowerCase();\n    return h === 'avature.net' || h.endsWith('.avature.net');\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  const cfg = resolveConfig(entry);\n  if (!cfg) throw new Error(`avature: cannot resolve origin for ${entry.name}`);\n  // ...fetch\n} catch (err) {\n  if (/cannot resolve origin/.test(err.message)) { console.warn(err.message); return []; }\n  throw err;\n}","preventionTips":["Use detect() to filter entries before fetching.","Validate that careers_url/api ends in avature.net during config linting.","Keep corporate careers pages in a separate field so they don't get misread as the avature origin."],"tags":["avature","config","host-derivation","validation"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}