santifer/career-ops · error · Error
decision must be one of
Error message
decision must be one of: ${[...DECISIONS].join(', ')} What it means
writeReuseDecision persists a CV-reuse decision record and validates the decision against the DECISIONS enum set before writing. If decision is not one of the enumerated values, it throws listing the allowed values. This prevents invalid decision labels from being archived into the application artifact bundle.
Solutions
- Read the exact allowed values from the thrown message (the DECISIONS set) and pass one verbatim, matching case and spelling.
- Import the decision constants from the module instead of hand-writing string literals, so renames are caught by the linter/runtime.
- If the value comes from persisted data or an older record, map/normalize it to the current enum before calling (with a fallback for unknown legacy labels).
- Log or inspect the actual value with typeof/value when unsure — undefined means the property name was mistyped in the call.
Example fix
// before
await writeReuseDecision({ paths, decision: 'full-reuse', score: 4.5 });
// after
import { DECISIONS } from './application-artifacts.mjs';
if (!DECISIONS.has('full-reuse')) throw new Error('unknown decision: full-reuse');
await writeReuseDecision({ paths, decision: DECISION_FULL_REUSE, score: 4.5 }); // use exported constant Defensive patterns
Strategy: validation
Validate before calling
import { DECISIONS } from './application-artifacts.mjs';
if (!DECISIONS.has(decision)) {
throw new Error(`decision '${decision}' not in: ${[...DECISIONS].join(', ')}`);
} Type guard
const isDecision = (d) => DECISIONS.has(d);
Try / catch
try {
await writeReuseDecision({ paths, decision, score });
} catch (err) {
if (err.message.startsWith('decision must be one of')) {
console.error(`Unknown decision '${decision}'. Allowed: ${err.message.match(/one of: (.*)$/)?.[1]}`);
} else throw err;
} Prevention
- Use the exported decision constants instead of raw string literals.
- Copy the exact enum values from the error message — they are listed verbatim.
- Normalize case/whitespace on values sourced from UIs or files before calling.
- When replaying persisted records, map legacy labels to the current enum first.
When it happens
Trigger: Calling writeReuseDecision with decision set to a misspelled or differently-cased value (e.g. 'Reuse', 'reuse_full', 'FULL_REUSE'), an empty string, null/undefined, or a raw value read from user input or an older schema version that predates the current enum.
Common situations: Refactoring renamed an enum member but a call site (or persisted JSON being replayed) still uses the old label; a UI dropdown sends free text; a script passes a CLI string directly without mapping it to the enum; comparing against a similarly named but distinct constant imported from the wrong module.
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
- Application answer state must be one of
- changedSections must be an array
- getEmployerProfile: id is required
- getEmployerProfile: id is required
- invalid format " " (use: )
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/dbe5d326aa9a3d44.
Report an issue: GitHub.
Appendix: source
Thrown at application-artifacts.mjs:87
join(paths.root, 'jd'),
join(paths.root, 'cv', 'source'),
paths.cv.tailored.root,
join(paths.root, 'decision'),
]) mkdirSync(directory, { recursive: true });
return paths;
}
/** Write an auditable CV reuse decision beside the application artifacts. */
export function writeReuseDecision(paths, {
decision,
score = null,
sourceCv = null,
currentJd = null,
previousSource = null,
changedSections = [],
userOverride = false,
}) {
if (!DECISIONS.has(decision)) throw new Error(`decision must be one of: ${[...DECISIONS].join(', ')}`);
if (!Array.isArray(changedSections)) throw new Error('changedSections must be an array');
ensureApplicationArtifactDirs(paths);
const record = {
schema_version: 1,
decision,
score,
source_cv: sourceCv,
current_jd: currentJd,
previous_source: previousSource,
changed_sections: changedSections,
user_override: Boolean(userOverride),
recorded_at: new Date().toISOString(),
};
writeFileSync(paths.decision.reuse, `${JSON.stringify(record, null, 2)}\n`);
return record;
}
// --help was swallowed by parseArgs's strict mode and reported as an unknownView on GitHub (pinned to aac998c7ed)