santifer/career-ops · error · Error

jobbankca: URL must use HTTPS: ${url}

Error message

jobbankca: URL must use HTTPS: ${url}

What it means

assertJobBankUrl enforces that all jobbankca requests use HTTPS. After the URL parses, it checks parsed.protocol !== 'https:' and throws this error for any http:// (or other scheme) URL. This protects credentials/query traffic from plaintext transport and blocks accidental non-HTTPS redirects.

Source

Thrown at providers/jobbankca.mjs:100

    : [];
  return { keywords };
}

/** @param {string} keyword @param {number} page */
export function buildFeedUrl(keyword, page) {
  const params = new URLSearchParams({ searchstring: keyword, locationstring: '', page: String(page) });
  return `${FEED_URL}?${params.toString()}`;
}

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

// Resolve an Atom element's inner text: unwrap CDATA, else decode entities.
function extractText(inner) {
  const cdata = inner.match(/^\s*<!\[CDATA\[([\s\S]*?)\]\]>\s*$/);
  if (cdata) return cdata[1].trim();
  return decodeEntities(inner).trim();
}

function tagText(block, tag) {
  const m = block.match(new RegExp(`<${tag}\\b[^>]*>([\\s\\S]*?)</${tag}>`, 'i'));
  return m ? extractText(m[1]) : '';
}

View on GitHub (pinned to 1696bec4d0)

Solutions

  1. Change the URL scheme to https:// in the provider config
  2. Check for a hardcoded http:// constant in your integration and update it
  3. If the source only offers http, find the official HTTPS endpoint instead of downgrading the check
  4. Validate the scheme in your own config loader to fail earlier with your own message

Example fix

// before
const url = 'http://jobbank.canada.ca/atom.xml';
// after
const url = 'https://jobbank.canada.ca/atom.xml';
Defensive patterns

Strategy: validation

Validate before calling

function isHttps(u) { try { return new URL(u).protocol === 'https:'; } catch { return false; } }
if (!isHttps(cfg.url)) throw new Error(`config: feed must be HTTPS: ${cfg.url}`);

Type guard

function isHttpsUrl(v) {
  try { return new URL(v).protocol === 'https:'; } catch { return false; }
}

Try / catch

try {
  assertJobBankUrl(url);
} catch (e) {
  if (e.message.includes('must use HTTPS')) {
    console.warn(`Upgrading http→https for ${url}`);
    return assertJobBankUrl(url.replace(/^http:/, 'https:'));
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a URL string starting with http:// (e.g. 'http://jobbank.canada.ca/atom.xml') or a scheme like ftp:// to assertJobBankUrl, typically copied from an old doc or hand-typed config.

Common situations: Portals.yml entry written with http:// by hand, a URL scraped from an old HTTP page, or a base URL constant defined without https. Also fires if someone passes a protocol-relative '//host/path' string? No — that fails parsing, but file:// or custom schemes parse and land here.

Related errors


AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01). Data as JSON: /api/errors/c491ceb41413f773. Report an issue: GitHub.