santifer/career-ops · error · Error
careerviet: URL must use HTTPS: ${url}
Error message
careerviet: URL must use HTTPS: ${url} What it means
The CareerViet provider enforces HTTPS on every request URL. When assertCareerVietUrl parses the URL but parsed.protocol is not 'https:', it throws this error. The provider scrapes server-rendered search pages over plain HTTPS; allowing http would silently downgrade transport and contradict the fixed-host security posture (only https://careerviet.vn is ever requested).
Source
Thrown at providers/careerviet.mjs:108
* apart; both wrap their <time> the same way.
*/
const UPDATED_DATE_RE = /Cập nhật(?:<!--[\s\S]*?-->)?\s*:?\s*(?:<\/span>)?\s*<time>([\d/-]+)<\/time>/i;
/** @param {any} ctx @param {number} ms */
function sleep(ctx, ms) {
if (typeof ctx?.sleep === 'function') return ctx.sleep(ms);
return new Promise((r) => setTimeout(r, ms));
}
/** @param {string} url */
function assertCareerVietUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`careerviet: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`careerviet: URL must use HTTPS: ${url}`);
if (parsed.hostname !== TRUSTED_HOST) {
throw new Error(`careerviet: untrusted hostname "${parsed.hostname}" — must be ${TRUSTED_HOST}`);
}
return url;
}
/**
* Collapse a markup fragment to its visible text.
* @param {string} fragment
* @returns {string}
*/
export function visibleText(fragment) {
return decodeEntities(
String(fragment ?? '')
.replace(/<!--[\s\S]*?-->/g, ' ')
.replace(/<[^>]+>/g, ' '),
)
.replace(/\s+/g, ' ')View on GitHub (pinned to 1696bec4d0)
Solutions
- Change the configured URL scheme to https://
- If the URL is built dynamically, use an https base: new URL(path, 'https://careerviet.vn')
- Remove any middleware/proxy that downgrades https to http for these requests
- Pre-validate with new URL(u).protocol === 'https:' before passing URLs into the provider
Example fix
// before
const url = `http://careerviet.vn/viec-lam?page=${page}`;
// after
const url = `https://careerviet.vn/viec-lam?page=${page}`; Defensive patterns
Strategy: validation
Validate before calling
function isHttpsUrl(value) {
if (typeof value !== 'string') return false;
try { return new URL(value).protocol === 'https:'; } catch { return false; }
}
if (!isHttpsUrl(entry.careers_url)) entry.careers_url = entry.careers_url.replace(/^http:/, 'https:'); Type guard
function isHttpsCareervietUrl(value) {
if (typeof value !== 'string') return false;
try {
const p = new URL(value);
return p.protocol === 'https:' && p.hostname === 'careerviet.vn';
} catch { return false; }
} Try / catch
try {
await provider.fetch(entry, ctx);
} catch (err) {
if (String(err.message).includes('must use HTTPS')) {
console.error(`${entry.name}: careerviet URLs must start with https://`);
} else throw err;
} Prevention
- Always configure https:// URLs for this provider — http is rejected by design
- Use an https base constant when constructing page URLs
- Avoid proxies that downgrade TLS for board scraping
- Lint provider entries for non-https schemes at startup
When it happens
Trigger: An entry or direct call supplying http://careerviet.vn/...; code that builds the URL from an http base constant; a proxy or test harness rewriting the scheme; calling assertCareerVietUrl on a constructed page URL where the base was http.
Common situations: Legacy config predating an HTTPS-only policy; developer testing against a local http mock of the board; URL copied from an insecure mirror or cached http link.
Related errors
- breezy: URL must use HTTPS: ${url}
- breezy: untrusted hostname "${parsed.hostname}" — must match
- careerviet: untrusted hostname "${parsed.hostname}" — must b
- getonbrd: URL must use HTTPS: ${url}
- glints: URL must use HTTPS: ${url}
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/45dba1f1495445e1.
Report an issue: GitHub.