santifer/career-ops · error · Error

himalayas: URL must use HTTPS: ${url}

Error message

himalayas: URL must use HTTPS: ${url}

What it means

Thrown by assertHimalayasUrl when the URL parses but its protocol is not https:. As with 204, the shipped fetch() only ever passes the hardcoded https FEED_URL constant, so this branch cannot fire from the public contract. It is an SSRF guard that activates if the feed constant is changed to an http: value or if the function is reused on caller input.

Source

Thrown at providers/himalayas.mjs:22

// Himalayas provider - board-wide remote jobs API
// (https://himalayas.app/jobs/api?limit=50). Returns { jobs: [...] }. The
// full feed is fetched so scan.mjs's title_filter / location_filter can do
// the local gating consistently with other zero-token board providers.
//
// Wire in via a `job_boards:` entry with `provider: himalayas`.

const FEED_URL = 'https://himalayas.app/jobs/api?limit=50';
const TRUSTED_HOST = 'himalayas.app';

/** @param {string} url */
function assertHimalayasUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`himalayas: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`himalayas: URL must use HTTPS: ${url}`);
  if (parsed.hostname !== TRUSTED_HOST) {
    throw new Error(`himalayas: untrusted hostname "${parsed.hostname}" - must be ${TRUSTED_HOST}`);
  }
  return url;
}

function cleanText(value) {
  return typeof value === 'string' ? value.trim() : '';
}

function cleanHimalayasUrl(value) {
  const raw = cleanText(value);
  if (!raw) return '';
  try {
    const parsed = new URL(raw);
    const host = parsed.hostname.toLowerCase();
    const trusted = host === TRUSTED_HOST || host.endsWith(`.${TRUSTED_HOST}`);
    return parsed.protocol === 'https:' && trusted ? parsed.href : '';

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Ensure FEED_URL (or any URL passed in) uses the https: scheme.
  2. If a dev mirror is http-only, gate the assert behind a test-only override rather than weakening the constant.
  3. Keep TRUSTED_HOST and the scheme check together so a host change is reviewed alongside the scheme.

Example fix

// before
const FEED_URL = 'http://himalayas.app/jobs/api?limit=50';

// after
const FEED_URL = 'https://himalayas.app/jobs/api?limit=50';
Defensive patterns

Strategy: validation

Validate before calling

// Verify scheme before driving the assert, for any URL you feed in.
function ensureHttps(url) {
  const u = new URL(url); // throws on malformed — see error 204
  if (u.protocol !== 'https:') throw new Error(`not https: ${url}`);
  return u.href;
}

Type guard

/** True only for an https: absolute URL. */
function isHttpsUrl(value) {
  try { return new URL(value).protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  return await himalayasProvider.fetch(entry, ctx);
} catch (err) {
  if (/URL must use HTTPS/.test(err.message)) {
    console.error(`himalayas: FEED_URL must be https — ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Editing FEED_URL to an http:// value (e.g. a staging host without TLS); reusing assertHimalayasUrl on entry-supplied input that uses http:. The unmodified provider's constant is https and never triggers this.

Common situations: Forgetting the https:// scheme when changing the feed host; pointing at a local/dev mirror over plain http during development.

Related errors


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