santifer/career-ops · error · Error
outcome-types.mjs: "${key}" is accepted by outcome.mjs but h
Error message
outcome-types.mjs: "${key}" is accepted by outcome.mjs but has no canonical meaning; add it to ALIASES or CANONICAL_OUTCOMES What it means
outcome-types.mjs self-validates its own tables at module load: every key in OUTCOME_MAP must either be a canonical outcome or an alias pointing at one. If a synonym was added to OUTCOME_MAP without declaring what it canonically means, the module throws at import time rather than letting the journal consumers silently read it as 'unknown'. This is an internal-consistency invariant for the developer/maintainer of the module, not end users.
Source
Thrown at lib/outcome-types.mjs:78
* result. What stops an omission here is the coverage check below and the drift
* test, not cleverness.
*/
const ALIASES = {
stage_reached: 'interview_progress',
interview: 'interview_progress',
offer: 'offer_received',
accepted: 'hired',
declined: 'offer_declined',
rejection: 'rejected',
ghosted: 'no_response',
};
// A synonym added to OUTCOME_MAP without a meaning here is a real decision, not
// a spelling. Fail loudly at load rather than let it read as unknown wherever
// the journal is consumed — which is the failure this module exists to end.
for (const key of Object.keys(OUTCOME_MAP)) {
if (!CANONICAL_OUTCOMES.includes(key) && !(key in ALIASES)) {
throw new Error(`outcome-types.mjs: "${key}" is accepted by outcome.mjs but has no canonical meaning; add it to ALIASES or CANONICAL_OUTCOMES`);
}
}
/**
* Resolve any accepted spelling to its canonical type.
*
* Applies the same normalization `outcome.mjs` applies before writing
* (lowercase, `-` → `_`), so a hand-edited journal saying `Offer-Declined`
* still resolves.
*
* @param {unknown} raw - A type as written in a journal or typed on the CLI.
* @returns {string|null} The canonical type, or null when unrecognized.
*/
export function canonicalOutcome(raw) {
const key = String(raw ?? '').trim().toLowerCase().replace(/-/g, '_');
if (CANONICAL_OUTCOMES.includes(key)) return key;
return ALIASES[key] ?? null;
}View on GitHub (pinned to 1696bec4d0)
Solutions
- Add the new key to ALIASES, mapping it to an existing canonical outcome
- Or add the key to CANONICAL_OUTCOMES if it is genuinely a new outcome type
- Run the module's test suite after any OUTCOME_MAP change to catch this at CI time
Example fix
// before (in OUTCOME_MAP) 'declined': null, // added with no meaning declared // after (in ALIASES) 'declined': 'rejected',
Defensive patterns
Strategy: validation
Validate before calling
// before import, in tests: assert every OUTCOME_MAP key is canonical or an alias for (const k of Object.keys(OUTCOME_MAP)) assert(CANONICAL_OUTCOMES.includes(k) || k in ALIASES, k);
Try / catch
try { const types = await import('./lib/outcome-types.mjs'); } catch (e) { console.error('outcome-types table inconsistent:', e.message); process.exit(1); } Prevention
- Add a unit test that imports outcome-types.mjs so load-time validation runs in CI
- When adding a synonym, update OUTCOME_MAP and ALIASES in the same commit
- Review OUTCOME_MAP diffs in code review for unmapped keys
When it happens
Trigger: Editing OUTCOME_MAP in lib/outcome-types.mjs to add a new synonym string without adding that key to ALIASES or to CANONICAL_OUTCOMES, then importing outcome.mjs.
Common situations: Adding a user-requested synonym ('rejected' → 'rejected') to the map but forgetting the ALIASES entry; a merge that brought in a partial key addition; renaming a canonical outcome without updating the map.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ${LOCAL_PATHS_FILE}: refusing "${path}" — ${why}
- plugin "${id}" inactive: ${reason}. Run `node doctor.mjs` fo
- APIFY_TOKEN not set — enable apify in config/plugins.yml and
- apify: entry ${entry.name} missing 'actor' (e.g. misceres/in
- apify: entry ${entry.name} has invalid field_map. Each of ti
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/81eb2f1ea40ded72.
Report an issue: GitHub.