santifer/career-ops · error · Error
oraclecloud: cannot derive API URL for ${entry.name}
Error message
oraclecloud: cannot derive API URL for ${entry.name} What it means
Thrown by oraclecloud's fetch() when resolveSite(entry) returns null — the entry has no api or careers_url that resolves to a valid Oracle FA cloud site. resolveSite() iterates [entry.api, entry.careers_url], parses each as a URL, checks protocol is https and hostname matches ORACLE_HOST_RE, then extracts siteNumber and lang from the path. If neither field yields a valid Oracle site, fetch() cannot proceed.
Source
Thrown at providers/oraclecloud.mjs:233
return out;
}
/** @type {Provider} */
export default {
id: 'oraclecloud',
detect(entry) {
try {
const site = resolveSite(entry);
return site ? { url: buildApiUrl(site, 0, PAGE_SIZE) } : null;
} catch {
return null;
}
},
async fetch(entry, ctx) {
const site = resolveSite(entry);
if (!site) throw new Error(`oraclecloud: cannot derive API URL for ${entry.name}`);
const maxPages = Number.isInteger(entry.max_pages) && entry.max_pages > 0
? Math.min(entry.max_pages, MAX_PAGES)
: MAX_PAGES;
const all = [];
let total = null;
for (let page = 0; page < maxPages; page++) {
const offset = page * PAGE_SIZE;
const apiUrl = buildApiUrl(site, offset, PAGE_SIZE);
assertOracleUrl(apiUrl); // SSRF guard before every fetch
if (page > 0) await sleep(INTER_PAGE_DELAY_MS, ctx);
const json = await fetchJsonWithRetry(ctx, apiUrl, {
redirect: 'error',
headers: { 'User-Agent': BROWSER_LIKE_USER_AGENT, Accept: 'application/json' },
}, RETRY_POLICY);
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Check the portals.yml entry has a valid careers_url: https://<tenant>.fa.<region>.oraclecloud.com/hcmUI/CandidateExperience/<lang>/sites/<siteNumber>
- Verify entry.api (if set) also matches the Oracle FA cloud pattern — resolveSite checks api first.
- Ensure detect() is called and its result respected before calling fetch() — skip entries where detect() returns null.
- If the entry was programmatically generated, add the careers_url field with the correct Oracle HCM URL.
Example fix
// before — entry missing or with wrong URL
job_boards:
oracle:
provider: oraclecloud
name: Acme
# careers_url missing
// after
job_boards:
oracle:
provider: oraclecloud
name: Acme
careers_url: 'https://acme.fa.eu.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1'
# optional overrides:
# siteNumber: 'CX_1'
# max_pages: 5 Defensive patterns
Strategy: validation
Validate before calling
const ORACLE_HOST_RE = /^[a-z0-9-]+\.fa\.(?:[a-z0-9-]+\.)?(?:ocs\.)?oraclecloud(?:[1-9][0-9]?)?\.com$/i;
/** Replicate resolveSite's logic to validate an entry before fetch. */
function canResolveOracleSite(entry) {
for (const raw of [entry.api, entry.careers_url]) {
if (typeof raw !== 'string' || !raw) continue;
try {
const p = new URL(raw);
if (p.protocol === 'https:' && ORACLE_HOST_RE.test(p.hostname)) return true;
} catch { /* skip */ }
}
return false;
}
if (!canResolveOracleSite(entry)) {
console.warn(`oraclecloud entry ${entry.name} cannot resolve site — skipping`);
continue;
} Type guard
/** @param {import('./_types.js').PortalEntry} entry @returns {boolean} */
function hasValidOracleUrl(entry) {
const url = entry.api || entry.careers_url;
return typeof url === 'string'
&& /\.fa\..*\.oraclecloud\.com/i.test(url)
&& url.startsWith('https://');
} Try / catch
try {
await oracleProvider.fetch(entry, ctx);
} catch (err) {
if (String(err.message).startsWith('oraclecloud: cannot derive API URL')) {
console.warn(`skipping ${entry.name}: no valid Oracle FA cloud URL`);
continue;
}
throw err;
} Prevention
- Call detect(entry) before fetch() — it wraps resolveSite in a try-catch returning null for invalid entries.
- Validate portals.yml entries at load time for required Oracle FA cloud URLs.
- Ensure config merges don't overwrite Oracle entry URLs with empty or wrong values.
When it happens
Trigger: resolveSite returns null when: (1) both entry.api and entry.careers_url are missing/empty/non-string; (2) they fail URL parsing; (3) protocol isn't https; (4) hostname fails ORACLE_HOST_RE. detect() catches the same resolveSite null and returns null, so this throw in fetch() means detect() was bypassed or the entry changed between detect() and fetch().
Common situations: The portals.yml entry for this provider has a missing or wrong-format careers_url. The entry was constructed by a batch script without the URL field. A config merge overwrote the correct URL with an empty or different value. The entry's careers_url points to a non-Oracle FA host (e.g. a legacy Taleo URL).
Related errors
- nofluffjobs: careers_url or api must be a trusted nofluffjob
- oraclecloud: invalid URL: ${url}
- oraclecloud: URL must use HTTPS: ${url}
- personio: cannot derive feed URL for ${entry.name}
- flowxtra: untrusted hostname "${parsed.hostname}" — must be
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/f28717a3bbcc230f.
Report an issue: GitHub.