santifer/career-ops · error · Error
unknown source in --sources
Error message
unknown source in --sources: ${source} What it means
parseSources splits the comma-separated `--sources` value, normalizes each name (lowercase, underscores/spaces to hyphens), dedupes, and validates each against the allowlist {techcrunch, prnewswire, guardian, hn}. Unknown names throw this error naming the offending source.
Solutions
- Use only: techcrunch, prnewswire, guardian, hn (comma-separated).
- Replace display names with canonical slugs: 'Hacker News' → hn, 'The Guardian' → guardian.
- Check spelling/normalization: hyphens, lowercase, no spaces.
- Omit --sources entirely to fall back to DEFAULT_SOURCES.
Example fix
// before node company-funded.mjs --sources techcrunch,hacker-news // after node company-funded.mjs --sources techcrunch,hn
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED = new Set(['techcrunch', 'prnewswire', 'guardian', 'hn']);
const CANON = { 'hacker news': 'hn', 'hackernews': 'hn', 'the guardian': 'guardian', 'pr newswire': 'prnewswire' };
function validSources(csv) {
const list = csv.split(',').map(s => CANON[s.trim().toLowerCase()] || s.trim().toLowerCase());
const bad = list.filter(s => !ALLOWED.has(s));
return bad.length ? { ok: false, bad } : { ok: true, list };
} Type guard
const isAllowedSource = (s) => ['techcrunch', 'prnewswire', 'guardian', 'hn'].includes(s);
Try / catch
try {
run(['--sources', sources]);
} catch (e) {
if (e.message.startsWith('unknown source in --sources:')) {
console.warn(`${e.message} — falling back to default sources`);
run([]); // no --sources → DEFAULT_SOURCES
} else throw e;
} Prevention
- Keep a canonical slug list near where source selection is configured.
- Prefer omitting --sources to accept DEFAULT_SOURCES.
- Normalize display names to slugs before passing.
- Update wrappers when new sources are added upstream.
When it happens
Trigger: `--sources techcrunch,twitter`, `--sources hacker-news` (canonical short name is `hn`), a misspelled source like `techcrunsh`, or a source that exists in the wider project but isn't enabled for this script.
Common situations: Guessing source slugs instead of checking documentation; using display names ('Hacker News', 'The Guardian') that normalize outside the allowlist; scripts generating source lists from stale config; a source was added upstream but this script's allowlist wasn't updated.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- --sort must be date or score
- Application answer state must be one of
- Application Answers section has
- decision must be one of
- --from and --to must both be supplied together (or neither…
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/81992b2bd986f778.
Report an issue: GitHub.
Appendix: source
Thrown at company-funded.mjs:146
}
if (!Number.isInteger(opts.months) || opts.months <= 0 || opts.months > 120) {
throw new Error('--months must be an integer from 1 to 120');
}
if (!['date', 'score'].includes(opts.sort)) {
throw new Error('--sort must be date or score');
}
return opts;
}
function parseSources(value) {
const out = String(value || '')
.split(',')
.map((s) => normalizeSourceName(s.trim()))
.filter(Boolean);
const unique = [...new Set(out)];
const allowed = new Set(['techcrunch', 'prnewswire', 'guardian', 'hn']);
for (const source of unique) {
if (!allowed.has(source)) throw new Error(`unknown source in --sources: ${source}`);
}
return unique.length ? unique : [...DEFAULT_SOURCES];
}
function normalizeSourceName(value) {
const s = String(value || '').toLowerCase().replace(/[_\s]+/g, '-');
if (s === 'hacker-news' || s === 'hackernews' || s === 'hn') return 'hn';
return s.replace(/-/g, '');
}
function compact(text) {
return String(text || '').replace(/\s+/g, ' ').trim();
}
function companySlug(name) {
return compact(name)
.toLowerCase()
.replace(/&/g, ' and ')View on GitHub (pinned to aac998c7ed)