santifer/career-ops · error · Error

manfred: URL must use HTTPS: ${url}

Error message

manfred: URL must use HTTPS: ${url}

What it means

Second guard in assertManfredUrl: after a successful parse, parsed.protocol must be 'https:'. Any other scheme is rejected to enforce TLS on the Manfred API call.

Source

Thrown at providers/manfred.mjs:35

//      `"lang must be one of the following values: EN, ES"`.
//
// Wire in via a `job_boards:` entry with `provider: manfred`.

const FEED_BASE = 'https://www.getmanfred.com/api/v2/public/offers';
const TRUSTED_HOST = 'www.getmanfred.com';
const OFFER_BASE = 'https://www.getmanfred.com/ofertas-empleo';
const VALID_LANGS = ['EN', 'ES'];
const DEFAULT_LANG = 'EN';

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

/** Resolve the feed language: `lang` on the entry, uppercased, else EN. */
export function resolveLang(entry) {
  const raw = typeof entry?.lang === 'string' ? entry.lang.trim().toUpperCase() : '';
  return VALID_LANGS.includes(raw) ? raw : DEFAULT_LANG;
}

// The feed reports currency as the SYMBOL, not an ISO code, and the observed
// values include a narrow-no-break-space variant of the euro sign. scan.mjs's
// salary_filter compares currencies case-insensitively as plain strings, so a
// symbol would never match a user's `currency: EUR` — map to ISO, and drop the
// field entirely rather than guess when the symbol is unknown.
const CURRENCY_BY_SYMBOL = new Map([

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Ensure the URL starts with https:// (Manfred's API is HTTPS-only).
  2. Verify with curl https://www.getmanfred.com/api/v2/public/offers.
  3. Fix any URL builder that omits or downgrades the scheme.

Example fix

// before
feedUrl = 'http://www.getmanfred.com/api/v2/public/offers'

// after
feedUrl = 'https://www.getmanfred.com/api/v2/public/offers'
Defensive patterns

Strategy: validation

Validate before calling

import { URL } from 'node:url';
export function isHttpsUrl(value) {
  try { return new URL(value).protocol === 'https:'; } catch { return false; }
}

Type guard

/** @param {string} url */
function isHttps(url) {
  try { return new URL(url).protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  assertManfredUrl(url);
} catch (err) {
  if (err.message.includes('HTTPS')) console.warn(`refusing non-HTTPS manfred URL: ${url}`);
  throw err;
}

Prevention

When it happens

Trigger: The URL parses but uses http://, ftp://, file://, or another non-https scheme. Most often a plain-http URL was constructed or configured.

Common situations: A legacy/test URL over HTTP; a feed base copied without the scheme; a derived offer URL lost its scheme during string building.

Related errors


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