santifer/career-ops · error · Error
workable: untrusted hostname "${parsed.hostname}" — must be
Error message
workable: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_WORKABLE_HOSTS].join(', ')} What it means
SSRF guard: the URL parsed and is https, but its hostname is not in ALLOWED_WORKABLE_HOSTS (apply.workable.com only). Built URLs always target apply.workable.com, so this fires only if a template host is changed OR the allowlist is emptied/mis-edited.
Source
Thrown at providers/workable.mjs:118
// same host, so this process never needs more than one in-flight request to
// it at a time.
let workableQueue = Promise.resolve();
function serialized(fn) {
const result = workableQueue.then(fn, fn);
workableQueue = result.then(() => undefined, () => undefined);
return result;
}
function assertWorkableUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`workable: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`workable: URL must use HTTPS: ${url}`);
if (!ALLOWED_WORKABLE_HOSTS.has(parsed.hostname)) {
throw new Error(`workable: untrusted hostname "${parsed.hostname}" — must be one of: ${[...ALLOWED_WORKABLE_HOSTS].join(', ')}`);
}
return url;
}
/**
* Extract the account slug from a tracked_companies entry's careers_url.
* @returns {string|null}
*/
export function resolveWorkableSlug(entry) {
const raw = entry && typeof entry.careers_url === 'string' ? entry.careers_url : '';
if (!raw) return null;
let parsed;
try {
parsed = new URL(raw);
} catch {
return null;
}
if (parsed.protocol !== 'https:') return null;View on GitHub (pinned to 9b17a8ac97)
Solutions
- Keep the templates on apply.workable.com and keep that host in ALLOWED_WORKABLE_HOSTS.
Example fix
// before const ALLOWED_WORKABLE_HOSTS = new Set([]); // after const ALLOWED_WORKABLE_HOSTS = new Set(['apply.workable.com']);
Defensive patterns
Strategy: validation
Validate before calling
for (const tpl of [widgetUrlFor, feedUrlFor]) {
const u = new URL(tpl("acme"));
if (!ALLOWED_WORKABLE_HOSTS.has(u.hostname))
throw new Error("workable: template host not in allowlist");
} Type guard
const isAllowedHost = (s, set) => { try { return set.has(new URL(s).hostname); } catch { return false; } }; Prevention
- Keep ALLOWED_WORKABLE_HOSTS non-empty and the templates on apply.workable.com.
- Add a CI test asserting both templates resolve to an allowed host.
When it happens
Trigger: A maintainer edits a URL template to a different host, or removes apply.workable.com from ALLOWED_WORKABLE_HOSTS.
Common situations: Refactor that accidentally clears the allowlist; a bad merge.
Related errors
- weworkremotely: untrusted hostname "${parsed.hostname}" - mu
- workable: invalid URL: ${url}
- workable: URL must use HTTPS: ${url}
- weworkremotely: invalid URL: ${url}
- weworkremotely: URL must use HTTPS: ${url}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/67106249177ac59b.
Report an issue: GitHub.