{"record":{"id":"da8cdf19ba3c999f","repo":"santifer/career-ops","slug":"rippling-url-must-use-https-url","errorCode":null,"errorMessage":"rippling: URL must use HTTPS: ${url}","messagePattern":"rippling: URL must use HTTPS: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/rippling.mjs","lineNumber":56,"sourceCode":"  const segment = parsed.pathname.split('/').filter(Boolean)[0] || '';\n  if (!SLUG_RE.test(segment)) return null;\n  return segment;\n}\n\n/** Build the board API URL for a validated slug. */\nfunction apiUrlForSlug(slug) {\n  return `${API_BASE}/${encodeURIComponent(slug)}/jobs`;\n}\n\n/** @param {string} url */\nfunction assertRipplingApiUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`rippling: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:') throw new Error(`rippling: URL must use HTTPS: ${url}`);\n  if (parsed.hostname !== API_HOST) {\n    throw new Error(`rippling: untrusted hostname \"${parsed.hostname}\" — must be ${API_HOST}`);\n  }\n  return url;\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'rippling',\n\n  detect(entry) {\n    const slug = resolveSlug(entry);\n    return slug ? { url: apiUrlForSlug(slug) } : null;\n  },\n\n  async fetch(entry, ctx) {\n    const slug = resolveSlug(entry);\n    if (!slug) throw new Error(`rippling: cannot derive API URL for ${entry.name}`);","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/rippling.mjs#L38-L74","documentation":"assertRipplingApiUrl rejects any URL whose protocol is not 'https:'. Since rippling builds its API URL from a constant API_BASE that already includes https://, this guard firing means the constant was changed to http or a URL was constructed outside the normal path.","triggerScenarios":"API_BASE was set to an http:// scheme; an externally-supplied http URL reached the guard; a test stub passed an http URL.","commonSituations":"Local development override switched API_BASE to http; a code change or environment variable altered the scheme.","solutions":["Restore API_BASE to its https:// form.","If a URL came from outside, upgrade the scheme: url.replace(/^http:/, 'https:').","Audit for any http://api.rippling.com references."],"exampleFix":"// before\nconst API_BASE = 'http://api.rippling.com/platform/api/ats/v1/board';\n// after\nconst API_BASE = 'https://api.rippling.com/platform/api/ats/v1/board';","handlingStrategy":"validation","validationCode":"function ensureHttps(raw) {\n  return typeof raw === 'string' ? raw.replace(/^http:\\/\\//i, 'https://') : raw;\n}\n// Pin API_BASE as a non-overridable constant\nconst API_BASE = 'https://api.rippling.com/platform/api/ats/v1/board';","typeGuard":"null","tryCatchPattern":"try {\n  await provider.fetch(entry, ctx);\n} catch (e) {\n  if (/must use HTTPS/.test(e.message)) {\n    console.error('[bug] rippling API_BASE is http — restore https');\n  } else throw e;\n}","preventionTips":["Keep API_BASE as a hardcoded https:// constant.","Do not allow runtime or env overrides of the scheme.","Add a CI assertion that API_BASE starts with https://."],"tags":["url-validation","https","provider","rippling","security"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}