santifer/career-ops · error · Error
runSeedScan: unknown seed
Error message
runSeedScan: unknown seed "${seedId}" What it means
runSeedScan looks up the requested seed source in the SEED_SOURCES registry; this library throws when the seedId key does not exist. It is a fail-fast guard so an unknown identifier aborts before any network fetching happens.
Solutions
- Print the valid seed IDs by inspecting the SEED_SOURCES object in scan-ats-full.mjs and pick one exactly
- Fix the seedId spelling in the command line or config
- Update to the current version if the seed was renamed and use its new ID
- Wrap the call in a check: if (!SEED_SOURCES[seedId]) list keys before running
Example fix
// before
await runSeedScan('ats-companies', opts, ctx, seenUrls, label);
// after
import { SEED_SOURCES } from './scan-ats-full.mjs';
if (!(seedId in SEED_SOURCES)) {
console.error(`Unknown seed "${seedId}". Valid: ${Object.keys(SEED_SOURCES).join(', ')}`);
process.exit(1);
}
await runSeedScan(seedId, opts, ctx, seenUrls, label); Defensive patterns
Strategy: validation
Validate before calling
import { SEED_SOURCES } from './scan-ats-full.mjs';
if (!(seedId in SEED_SOURCES)) {
throw new Error(`Unknown seed "${seedId}". Valid seeds: ${Object.keys(SEED_SOURCES).join(', ')}`);
} Try / catch
try {
await runSeedScan(seedId, opts, ctx, seenUrls, label);
} catch (err) {
if (String(err.message).startsWith('runSeedScan: unknown seed')) {
console.error(`${err.message}. Valid seeds: ${Object.keys(SEED_SOURCES).join(', ')}`);
} else throw err;
} Prevention
- List SEED_SOURCES keys before passing a seedId on the CLI
- Keep seed IDs in a single config constant referenced by both caller and registry
- Validate user-supplied seed names at argument-parse time
When it happens
Trigger: Calling runSeedScan(seedId, ...) with a seedId that is not a key of SEED_SOURCES, e.g. a typo, a renamed/removed seed, or an ID read from config that the CLI never registered.
Common situations: Users pass a seed name on the CLI or in a config file after a version renamed seeds; scripts hardcode an old seed ID; programmatic callers build the ID dynamically and mistype it.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Application Answers section has
- requires a path
- ⚠️ Could not save report
- --from and --to must both be supplied together (or neither…
- --from ( ) must not be after --to ( ).
AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16).
Data as JSON: /api/errors/7aad84f25d826c02.
Report an issue: GitHub.
Appendix: source
Thrown at scan-ats-full.mjs:556
const SEED_PROVIDERS = [greenhouse, lever, ashby];
/**
* Scan a VC portfolio seed source and return matching job offers.
* Companies are converted to PortalEntry shape, then each ATS provider's
* detect() is tried in order (greenhouse → lever → ashby). The first hit
* wins and its fetch() is called — identical to how portals.yml tracked
* companies flow through scan.mjs.
*
* @param {string} seedId Key from SEED_SOURCES (e.g. 'yc').
* @param {object} opts Parsed CLI options.
* @param {object} ctx HTTP context from makeHttpCtx().
* @param {Set} seenUrls Shared dedup set (mutated in place).
* @param {string} label Human-readable source label for logs.
* @returns {Promise<object[]>} New job offers (same shape as ATS scan offers).
*/
export async function runSeedScan(seedId, opts, ctx, seenUrls, label) {
const source = SEED_SOURCES[seedId];
if (!source) throw new Error(`runSeedScan: unknown seed "${seedId}"`);
let companies;
try {
companies = await source.fetch();
} catch (err) {
console.error(`⚠️ ${seedId}: could not fetch portfolio — ${err.message}`);
return [];
}
// Apply the --limit cap here too (by slug, consistent with sampleCompanies).
const capped = opts.limit < companies.length
? (opts.shuffle
? (() => { const c = companies.slice(); for (let i = c.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [c[i], c[j]] = [c[j], c[i]]; } return c.slice(0, opts.limit); })()
: companies.slice(0, opts.limit))
: companies;
const cutoff = Date.now() - opts.sinceDays * 86_400_000;
const offers = [];View on GitHub (pinned to e7abd431fc)