{"record":{"id":"fa4d28b05f4b0c5a","repo":"santifer/career-ops","slug":"consider-entry-name-needs-an-https-careers-url","errorCode":null,"errorMessage":"consider: ${entry.name} needs an https careers_url on a public host","messagePattern":"consider: (.+?) needs an https careers_url on a public host","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"providers/consider.mjs","lineNumber":150,"sourceCode":"  }\n  if (Array.isArray(job.normalizedLocations) && job.normalizedLocations.length) {\n    return job.normalizedLocations.map(l => l?.label || l?.value).filter(Boolean).join(', ');\n  }\n  return job.remote ? 'Remote' : '';\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'consider',\n\n  detect(entry) {\n    const origin = resolveOrigin(entry);\n    return entry.consider_board && origin ? { url: origin + ENDPOINT_PATH } : null;\n  },\n\n  async fetch(entry, ctx) {\n    const origin = resolveOrigin(entry);\n    if (!origin) throw new Error(`consider: ${entry.name} needs an https careers_url on a public host`);\n    if (!entry.consider_board) throw new Error(`consider: ${entry.name} needs a 'consider_board' id in portals.yml`);\n    const size = Number.isInteger(entry.consider_size) && entry.consider_size > 0 ? entry.consider_size : DEFAULT_SIZE;\n\n    // Perform the CSRF handshake before the POST. ctx._acquireHandshake is a\n    // test seam: set it to a stub in unit tests so no real network call is made.\n    const { cookie, csrfToken } = await (\n      typeof ctx._acquireHandshake === 'function'\n        ? ctx._acquireHandshake(origin)\n        : acquireCsrfHandshake(origin)\n    );\n\n    const csrfHeaders = {};\n    if (cookie) csrfHeaders.cookie = cookie;\n    if (csrfToken) csrfHeaders['x-csrf-token'] = csrfToken;\n\n    const json = await ctx.fetchJson(origin + ENDPOINT_PATH, {\n      method: 'POST',\n      // redirect:'error' so a 3xx from the (config-driven) board host can't be","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/consider.mjs#L132-L168","documentation":"The Consider provider requires each portals.yml entry to have a careers_url that resolves to an HTTPS origin on a public host; resolveOrigin(entry) returns null otherwise, and fetch throws this error. Consider's CSRF-handshake + POST flow must target a reachable public https endpoint, so private/relative/non-https origins are rejected up front. The error names the offending entry so the bad config line is easy to find.","triggerScenarios":"Scanning an entry with provider consider whose careers_url is missing, is http:// instead of https://, is localhost/private-IP, or is otherwise unresolvable to a public https origin.","commonSituations":"Copy-pasting an internal staging careers URL (localhost or intranet host) into portals.yml; omitting careers_url entirely while setting consider_board; a typo making the URL unparseable so resolveOrigin returns null.","solutions":["Add or fix careers_url on the entry so it is a full https:// URL on a public host (e.g. https://jobs.company.com).","Confirm the scheme is https (http:// is rejected) and the host is public — no localhost, 127.0.0.1, or private ranges.","Verify consider_board is set too, since fixing the origin alone leads straight to the next error about the missing board id.","Test the origin resolves with a quick `new URL(entry.careers_url)` and protocol/hostname check before re-running the scan."],"exampleFix":"// before\n- name: mycompany\n  provider: consider\n  consider_board: abc123\n// after\n- name: mycompany\n  provider: consider\n  careers_url: https://jobs.mycompany.com\n  consider_board: abc123","handlingStrategy":"validation","validationCode":"function isPublicHttpsOrigin(u) { try { const p = new URL(u); return p.protocol === 'https:' && !['localhost','127.0.0.1'].includes(p.hostname) && !p.hostname.endsWith('.local') && !/^10\\./.test(p.hostname) && !/^192\\.168\\./.test(p.hostname); } catch { return false; } }\nif (entry.provider === 'consider' && !isPublicHttpsOrigin(entry.careers_url)) throw new Error(`consider entry '${entry.name}' needs a public https careers_url`);","typeGuard":"const hasPublicHttpsOrigin = (u) => { try { const p = new URL(u); return p.protocol === 'https:' && p.hostname !== 'localhost' && p.hostname.includes('.'); } catch { return false; } };","tryCatchPattern":null,"preventionTips":["Always use the production https careers URL, never staging or localhost","Set careers_url and consider_board together when onboarding a consider entry","Sanity-check the URL parses and has an https scheme in a config linter","If a scan skips an entry with this error, fix the origin before assuming the board id is wrong"],"tags":["config","url-validation","consider","https"],"backgroundTag":"invalid-url-format","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"}