santifer/career-ops · error · Error

gem: URL must use HTTPS: ${url}

Error message

gem: URL must use HTTPS: ${url}

What it means

gem.mjs throws this in assertGemUrl() after the URL parses successfully but its protocol is not 'https:'. It enforces TLS for the Gem GraphQL endpoint and rejects http:/file:/data: schemes. Since the validated value is the constant GEM_API_URL, a live throw indicates that constant was set to an http:// (or other-scheme) URL.

Source

Thrown at providers/gem.mjs:113

function buildJobDescriptionText(posting) {
  const intro = htmlToText(posting?.jobPostSectionHtml?.introHtml);
  const body = htmlToText(posting?.descriptionHtml);
  const outro = htmlToText(posting?.jobPostSectionHtml?.outroHtml);
  const compensation = htmlToText(posting?.compensationHtml);

  const text = [intro, body, outro].filter(Boolean).join('\n\n');
  return compensation ? [text, `Compensation: ${compensation}`].filter(Boolean).join('\n\n') : text;
}

/** @param {string} url */
function assertGemUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`gem: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`gem: URL must use HTTPS: ${url}`);
  if (!ALLOWED_GEM_HOSTS.has(parsed.hostname))
    throw new Error(`gem: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_GEM_HOSTS].join(', ')}`);
  return url;
}

/** @param {import('./_types.js').PortalEntry} entry */
function resolveBoardId(entry) {
  const raw = typeof entry.careers_url === 'string' ? entry.careers_url : '';
  if (!raw) return null;
  let parsed;
  try {
    parsed = new URL(raw);
  } catch {
    return null;
  }
  if (parsed.hostname !== 'jobs.gem.com') return null;
  const match = parsed.pathname.match(/^\/([^/?#]+)/);
  return match ? match[1] : null;

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Keep GEM_API_URL on https:// (the public endpoint is TLS-only).
  2. If you need local interception, point your proxy at the HTTPS endpoint and trust the proxy's CA instead of downgrading the scheme.
  3. Remove any test that passes an http URL unless it is explicitly asserting this error.

Example fix

// before
const GEM_API_URL = 'http://jobs.gem.com/api/public/graphql/batch';

// after
const GEM_API_URL = 'https://jobs.gem.com/api/public/graphql/batch';
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the Gem endpoint scheme at startup.
function checkGemScheme() {
  const u = new URL('https://jobs.gem.com/api/public/graphql/batch');
  if (u.protocol !== 'https:') throw new Error('gem endpoint must be HTTPS');
}

Prevention

When it happens

Trigger: GEM_API_URL was changed to 'http://jobs.gem.com/...' (e.g. for local debugging through a non-TLS proxy); a test calls assertGemUrl('http://jobs.gem.com/api/public/graphql/batch').

Common situations: A developer disables TLS locally to intercept traffic with mitmproxy on http://localhost and repoints GEM_API_URL; a stale fork still references the pre-HTTPS endpoint; a CI env var overrode the constant with an http URL.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/5f6c85165ae48efe. Report an issue: GitHub.