{"record":{"id":"f0adf71a3dca7ecf","repo":"santifer/career-ops","slug":"solidjobs-invalid-url-url","errorCode":null,"errorMessage":"solidjobs: invalid URL: ${url}","messagePattern":"solidjobs: invalid URL: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/solidjobs.mjs","lineNumber":25,"sourceCode":"// Available divisions: it, engineering, marketing, sales, hr, logistics, finances, other\n// API docs: https://solid.jobs/public-api/offers/{division}?campaign={campaign}\n\nconst ALLOWED_HOSTS = new Set(['solid.jobs']);\n\n/**\n * Validates that the provided URL is a trusted SolidJobs API endpoint.\n * Enforces HTTPS protocol, strict hostname matching, and required path prefix.\n * \n * @param {string} url - The URL string to validate.\n * @returns {string} The validated URL string.\n * @throws {Error} If the URL is malformed, uses non-HTTPS, has an untrusted host, or wrong path.\n */\nfunction assertUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`solidjobs: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:') throw new Error(`solidjobs: URL must use HTTPS: ${url}`);\n  if (!ALLOWED_HOSTS.has(parsed.hostname))\n    throw new Error(`solidjobs: untrusted hostname \"${parsed.hostname}\" — must be solid.jobs`);\n  if (!parsed.pathname.startsWith('/public-api/offers/'))\n    throw new Error(`solidjobs: URL path must start with /public-api/offers/: ${url}`);\n  return url;\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'solidjobs',\n\n  /**\n   * Attempts to detect if the provider can handle the given entry by checking the careers_url.\n   * * @param {{ careers_url?: string, name?: string }} entry - The configuration entry.\n   * @returns {{url: string} | null} An object with the matched URL, or null if not matched.\n   */","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/solidjobs.mjs#L7-L43","documentation":"assertUrl wraps new URL(entry.careers_url) in try/catch and throws 'solidjobs: invalid URL' when the constructor cannot parse the string. This is the first of four sequential validations in assertUrl (parse → https → host → path); it fires before the host/path checks, so the value is not even a syntactically valid URL.","triggerScenarios":"entry.careers_url is a non-empty string that new URL rejects: missing scheme (e.g. 'solid.jobs/public-api/offers/it'), contains spaces or stray characters, or is a malformed paste. (An empty/missing value is caught earlier by the 'careers_url required' guard at line 62.)","commonSituations":"YAML typo, a copy-paste that dropped the 'https://' scheme, an unquoted YAML scalar parsed oddly, or a trailing/leading whitespace artifact.","solutions":["Prefix the value with https:// so it is an absolute URL","Quote the scalar in portals.yml if it contains special characters","Trim stray whitespace/quotes around the URL","Use the full form https://solid.jobs/public-api/offers/<division>"],"exampleFix":"# before\n- name: SolidJobs IT\ncareers_url: solid.jobs/public-api/offers/it\n# after\n- name: SolidJobs IT\ncareers_url: https://solid.jobs/public-api/offers/it","handlingStrategy":"validation","validationCode":"// Reject malformed careers_url before the provider fetches.\nfunction isValidUrl(v) {\n  if (typeof v !== 'string' || !v) return false;\n  try { new URL(v); return true; } catch { return false; }\n}\nif (!isValidUrl(entry.careers_url)) {\n  console.warn(`${entry.name}: careers_url is not a valid absolute URL`);\n}","typeGuard":"/** @param {unknown} v @returns {v is string} */\nfunction isValidUrl(v) {\n  if (typeof v !== 'string' || !v) return false;\n  try { new URL(v); return true; } catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Run a config-lint pass that parses every careers_url with new URL before scanning.","Always include the https:// scheme in YAML scalars.","Quote YAML scalars that could be mis-parsed."],"tags":["url-validation","config","solidjobs","portals-yml"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}