{"record":{"id":"6dfbfadfa0fbec74","repo":"santifer/career-ops","slug":"manfred-url-must-use-https-url","errorCode":null,"errorMessage":"manfred: URL must use HTTPS: ${url}","messagePattern":"manfred: URL must use HTTPS: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/manfred.mjs","lineNumber":43,"sourceCode":"// The full catalogue in one response runs ~2.3MB and takes 8-9.6s to arrive\n// even on a clean connection — right against the shared 10s default timeout,\n// so any network jitter aborts it. Give it real headroom rather than relying\n// on retry alone to paper over a structurally near-timeout request.\nconst FETCH_TIMEOUT_MS = 25_000;\nconst TRUSTED_HOST = 'www.getmanfred.com';\nconst OFFER_BASE = 'https://www.getmanfred.com/ofertas-empleo';\nconst VALID_LANGS = ['EN', 'ES'];\nconst DEFAULT_LANG = 'EN';\n\n/** @param {string} url */\nfunction assertManfredUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`manfred: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:') throw new Error(`manfred: URL must use HTTPS: ${url}`);\n  if (parsed.hostname !== TRUSTED_HOST) {\n    throw new Error(`manfred: untrusted hostname \"${parsed.hostname}\" — must be ${TRUSTED_HOST}`);\n  }\n  return url;\n}\n\n/** Resolve the feed language: `lang` on the entry, uppercased, else EN. */\nexport function resolveLang(entry) {\n  const raw = typeof entry?.lang === 'string' ? entry.lang.trim().toUpperCase() : '';\n  return VALID_LANGS.includes(raw) ? raw : DEFAULT_LANG;\n}\n\n// The feed reports currency as the SYMBOL, not an ISO code, and the observed\n// values include a narrow-no-break-space variant of the euro sign. scan.mjs's\n// salary_filter compares currencies case-insensitively as plain strings, so a\n// symbol would never match a user's `currency: EUR` — map to ISO, and drop the\n// field entirely rather than guess when the symbol is unknown.\nconst CURRENCY_BY_SYMBOL = new Map([","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/santifer/career-ops/blob/e7abd431fce9348a95261acac9e0c14779c35df8/providers/manfred.mjs#L25-L61","documentation":"After parsing succeeds, assertManfredUrl() enforces that the feed is only fetched over HTTPS. Any URL whose protocol is not 'https:' (typically http:, or schemes like ftp:) is rejected with this error. This is a deliberate transport-security pin so credentials and job-seeker data are never sent over plaintext.","triggerScenarios":"Configuring a Manfred feed/careers_url with an http:// scheme, e.g. http://getmanfred.com/api/feed, or a URL with an unexpected scheme (ftp:, file:) that still parses as a URL.","commonSituations":"Copying an http:// link from old docs or a local proxy setup; a config migration that rewrote hosts but not schemes; forgetting that localhost test URLs must also be https or use a different provider path.","solutions":["Change the URL scheme to https:// in the entry config.","If you intentionally need plain HTTP (e.g. a local test), use a local HTTPS terminator or mock the fetchJson context rather than downgrading the check.","Verify no redirect/rewrite step upstream is emitting http:// links into the config."],"exampleFix":"// before\nconst url = 'http://getmanfred.com/api/feed';\n// after\nconst url = 'https://getmanfred.com/api/feed';","handlingStrategy":"validation","validationCode":"const u = new URL(entry.careers_url);\nif (u.protocol !== 'https:') throw new Error(`${entry.name}: careers_url must be https:// (got ${u.protocol})`);","typeGuard":"const isHttpsUrl = (v) => { try { return new URL(v).protocol === 'https:'; } catch { return false; } };","tryCatchPattern":"try {\n  await provider.fetch(entry, ctx);\n} catch (err) {\n  if (String(err.message).startsWith('manfred: URL must use HTTPS')) {\n    console.error('Fix: change the entry URL scheme to https://');\n    return;\n  }\n  throw err;\n}","preventionTips":["Always write https:// explicitly in config; never copy bare hostnames.","Add a startup check that rejects non-https URLs in all provider entries.","Watch for redirects that downgrade to http when testing locally — pin scheme in tests too."],"tags":["url","https","security","validation"],"backgroundTag":"invalid-url","analyzedSha":"e7abd431fce9348a95261acac9e0c14779c35df8","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}