{"record":{"id":"876619ea113c64f8","repo":"santifer/career-ops","slug":"agentic-jobs-invalid-url-url","errorCode":null,"errorMessage":"agentic-jobs: invalid URL: ${url}","messagePattern":"agentic-jobs: invalid URL: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/agentic-jobs.mjs","lineNumber":45,"sourceCode":"// boards; MAX_PAGES is a hard stop regardless.\n//\n// Wire in via a `job_boards:` entry with `provider: agentic-jobs`.\n\nconst SITE_ORIGIN = 'https://agentic-engineering-jobs.com';\nconst API_BASE = `${SITE_ORIGIN}/api/v1`;\nconst TRUSTED_HOST = 'agentic-engineering-jobs.com';\nconst PAGE_SIZE = 50; // fixed by the API (meta.per_page)\nconst MAX_PAGES = 40; // safety cap on request count (40*50 = 2000 postings)\nconst MAX_JOBS = 2000;\nconst PAGE_DELAY_MS = 2100; // stays under the documented 30 req/60s limit\n\n/** @param {string} url */\nfunction assertAgenticUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`agentic-jobs: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:') throw new Error(`agentic-jobs: URL must use HTTPS: ${url}`);\n  if (parsed.hostname !== TRUSTED_HOST) {\n    throw new Error(`agentic-jobs: untrusted hostname \"${parsed.hostname}\" — must be ${TRUSTED_HOST}`);\n  }\n  return url;\n}\n\nconst regionNames = new Intl.DisplayNames(['en'], { type: 'region' });\n\n/**\n * Resolve a two-letter ISO country code to an English name. Returns '' for\n * anything that isn't a resolvable two-letter code. Exported for tests.\n * @param {unknown} code\n */\nexport function countryName(code) {\n  if (typeof code !== 'string' || !/^[A-Za-z]{2}$/.test(code)) return '';\n  try {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/providers/agentic-jobs.mjs#L27-L63","documentation":"assertAgenticUrl in providers/agentic-jobs.mjs throws this when the URL passed to the agentic-jobs provider cannot be parsed by the URL constructor. The provider validates feed URLs in three stages — parse, HTTPS, trusted hostname — and this is the first stage, rejecting syntactically invalid URL strings before any fetch is attempted.","triggerScenarios":"new URL(url) throws for the given string: missing scheme, empty string, illegal characters, spaces, or a non-URL config value (path fragment, placeholder like '${FEED_URL}' left unsubstituted).","commonSituations":"portals.yml entry missing 'https://'; YAML multi-line folding inserting whitespace; unset env var interpolating 'undefined' into the URL; copy-paste dropping part of the URL.","solutions":["Repair the URL so it is a valid absolute URL (add the scheme, remove stray characters/whitespace).","Check the config source for unset variables or leftover placeholders.","Run `new URL(url)` in a REPL to reproduce the parse error and pinpoint the malformed part."],"exampleFix":"// before\nfetchAgenticJobs(url) // url = 'agenticjobs.dev/api' — no scheme\n// after\nfetchAgenticJobs('https://agenticjobs.dev/api')","handlingStrategy":"validation","validationCode":"try { new URL(rawUrl); } catch { throw new Error(`invalid agentic-jobs feed URL: ${rawUrl}`); }","typeGuard":"function isParsableUrl(s) {\n  try { new URL(s); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await fetchAgenticJobs(url);\n} catch (e) {\n  if (String(e.message).startsWith('agentic-jobs: invalid URL')) {\n    console.error(`Malformed feed URL in config: ${url}`);\n    return null;\n  } else throw e;\n}","preventionTips":["Store complete absolute URLs in config; never concatenate unvalidated fragments.","Check for unset env vars/placeholders that interpolate 'undefined' into URLs.","Validate all configured URLs with new URL() at startup."],"tags":["url-validation","provider","configuration"],"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"}