santifer/career-ops · error · Error

themuse: URL must use HTTPS

Error message

themuse: URL must use HTTPS: ${url}

What it means

assertMuseUrl() requires every URL to use the https: protocol. The URL parsed successfully but its scheme is something else (http:, ftp:, javascript:, etc.), so the provider refuses it. This is a deliberate security/consistency guard so the provider never fetches or emits insecure or exotic-scheme URLs.

Solutions

  1. Change the scheme to https:// in the config or calling code.
  2. Search your portals.yml for http:// occurrences and update them to https://.
  3. If the upstream only serves http, do not downgrade the check — proxy or drop the entry; the Muse API itself is HTTPS-only.

Example fix

// before
assertMuseUrl('http://www.themuse.com/api/v2/jobs?page=0');
// after
assertMuseUrl('https://www.themuse.com/api/v2/jobs?page=0');
Defensive patterns

Strategy: validation

Validate before calling

function isHttpsUrl(value) {
  try { return new URL(value).protocol === 'https:'; } catch { return false; }
}
// pre-check: entries.filter(e => !isHttpsUrl(e.url)) → fix before running the scan

Type guard

const isHttps = (v) => {
  if (typeof v !== 'string') return false;
  try { return new URL(v).protocol === 'https:'; } catch { return false; }
};

Try / catch

try {
  return await provider.fetch(entry, ctx);
} catch (err) {
  if (String(err.message).includes('must use HTTPS')) {
    const fixed = entry.url.replace(/^http:/, 'https:');
    console.warn(`Upgraded ${entry.name} to ${fixed}; update portals.yml`);
    return null;
  }
  throw err;
}

Prevention

When it happens

Trigger: assertMuseUrl(url) is called with a parseable URL whose parsed.protocol !== 'https:' — typically an http:// link in the config or a schemeless-relative URL that resolved against a file: base.

Common situations: Copy-pasting a plain-http link from an old doc; a config entry written as 'http://www.themuse.com/...'; code building a URL from an env var defaulting to http.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/640c2df6fb58eabf. Report an issue: GitHub.

Appendix: source

Thrown at providers/themuse.mjs:90

      // unbounded value would otherwise stall this board's fetch for as long
      // as the server says, defeating the point of a bounded backoff.
      const retryAfterMs = parseRetryAfterMs(err?.retryAfter);
      const delayMs = retryAfterMs !== null ? Math.min(retryAfterMs, RETRY_MAX_DELAY_MS * 4) : (backoff + Math.random() * 250);
      await sleep(delayMs, ctx);
    }
  }
  throw lastErr;
}

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

/**
 * Normalize a single result from the Muse API response. Exported for unit tests.
 *
 * Field mapping:
 *   name              → title
 *   refs.landing_page → url
 *   company.name      → company
 *   locations[0].name → location
 *
 * Returns null when required fields (title or url) are missing or invalid.
 *
 * @param {any} j

View on GitHub (pinned to aac998c7ed)