{"record":{"id":"b9fd59f95fc44b9c","repo":"santifer/career-ops","slug":"application-answer-state-must-be-one-of-val","errorCode":null,"errorMessage":"Application answer state must be one of: ${[...VALID_STATES].join(', ')}","messagePattern":"Application answer state must be one of: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"application-answers.mjs","lineNumber":39,"sourceCode":"  for (const key of keys) {\n    const value = object?.[key];\n    if (Array.isArray(value)) {\n      if (value.length > 0) return value;\n      continue;\n    }\n    if (value !== undefined && value !== null && String(value).trim()) return value;\n  }\n  return '';\n}\n\nfunction list(value) {\n  return Array.isArray(value) ? value : [];\n}\n\nfunction normalizeState(state) {\n  const normalized = inline(state || 'filled').toLowerCase();\n  if (!VALID_STATES.has(normalized)) {\n    throw new Error(`Application answer state must be one of: ${[...VALID_STATES].join(', ')}`);\n  }\n  return normalized;\n}\n\nfunction normalizeDate(date) {\n  return inline(date || new Date().toISOString().slice(0, 10));\n}\n\nfunction quoteBlock(value) {\n  const text = String(value ?? '').replace(/\\r\\n/g, '\\n').trim();\n  if (!text) return '> Not recorded.';\n  return text.split('\\n').map((line) => `> ${line}`).join('\\n');\n}\n\nfunction qaLines(entries, { labelKeys, valueKeys, fallback }) {\n  if (entries.length === 0) return ['- None captured.'];\n\n  return entries.flatMap((entry, index) => {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/application-answers.mjs#L21-L57","documentation":"Validation in `normalizeState` (application-answers.mjs): the answer record's `state` field, after lowercasing and whitespace-normalizing, must be a member of `VALID_STATES` (defined as the set `['filled', 'submitted']`). Any other value — including common synonyms like 'draft', 'pending', 'done' — is rejected to keep the persisted state machine uniform.","triggerScenarios":"Passing `--state draft`, `--state pending`, `--state DONE` (case ok but value wrong), `--state Applied`, or any non-`filled`/`submitted` token to the CLI; calling `normalizeState('saved')` programmatically; JSON input with `{ \"state\": \"complete\" }`.","commonSituations":"User types a synonym that 'feels' right; integration with another tool whose status vocabulary differs; copy-paste from a tracker that uses `Applied`/`Submitted`-style labels; migrating from an older schema that allowed free-form state.","solutions":["Use exactly one of `filled` or `submitted` (case-insensitive, surrounding whitespace tolerated).","Map your upstream statuses onto these two before invoking the script: `Applied`/`Saved`/`Drafted` → `filled`; `Submitted`/`Sent` → `submitted`.","Re-read the usage line: `--state filled|submitted`.","If you genuinely need a third state, extend `VALID_STATES` and update the persistence format intentionally — don't smuggle new values through.","Add a unit test listing accepted and rejected values."],"exampleFix":"// before\nnode application-answers.mjs --report r.md --input a.json --state submitted-to-portal\n// after\nnode application-answers.mjs --report r.md --input a.json --state submitted","handlingStrategy":"validation","validationCode":"const VALID = new Set(['filled', 'submitted']);\nfunction normalizeState(s) {\n  const n = String(s || '').trim().toLowerCase();\n  if (!VALID.has(n)) throw new Error(`state must be filled|submitted, got: ${s}`);\n  return n;\n}","typeGuard":"function isAnswerState(s) {\n  return typeof s === 'string' &&\n    ['filled', 'submitted'].includes(s.trim().toLowerCase());\n}","tryCatchPattern":null,"preventionTips":["Map upstream statuses onto filled/submitted before invoking.","Treat the state vocabulary as part of the schema — don't extend it ad hoc.","Document the two accepted values wherever the CLI is referenced.","Add tests enumerating accepted and rejected values."],"tags":["validation","cli","state-machine","application-answers"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}