santifer/career-ops · error · Error

Application answer state must be one of

Error message

Application answer state must be one of: ${[...VALID_STATES].join(', ')}

What it means

application-answers.mjs validates the application answer state against the fixed set VALID_STATES = {'filled','submitted'}. normalizeState lowercases the input and throws when it is not a member, listing the allowed values in the message. This keeps the application-answers snapshot file limited to canonical states.

Solutions

  1. Change the state string to a canonical value: 'filled' or 'submitted' (case-insensitive; input is lowercased).
  2. Map foreign state names to canonical ones at the boundary before saving, e.g. draft -> filled, done/sent -> submitted.
  3. Print VALID_STATES or read the error message to see the exact allowed set before retrying.

Example fix

// before
saveAnswers({ state: 'draft', answers });
// after
const ALIASES = { draft: 'filled', done: 'submitted', sent: 'submitted' };
const state = ALIASES[rawState] ?? rawState;
saveAnswers({ state, answers });
Defensive patterns

Strategy: validation

Validate before calling

const VALID_STATES = new Set(['filled', 'submitted']);
if (!VALID_STATES.has(String(state || 'filled').toLowerCase())) {
  throw new Error(`state must be filled or submitted, got: ${state}`);
}

Type guard

function isCanonicalAnswerState(v) {
  return typeof v === 'string' && ['filled', 'submitted'].includes(v.toLowerCase());
}

Try / catch

try {
  saveAnswers({ state, answers });
} catch (err) {
  if (String(err.message).startsWith('Application answer state must be one of')) {
    console.error(`Invalid state "${state}"; use filled or submitted`);
    process.exitCode = 2;
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling normalizeState or any API that routes state through it (write/save of an application answer record) with state values like 'draft', 'complete', 'FILLED ' that isn't in the set, an empty string, or a boolean/number instead of a string.

Common situations: Migrating from another tool whose states were 'draft'/'done'; typo-ing 'submited'; wiring a UI dropdown that emits different labels; hand-editing the JSON state file with a non-canonical state.

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


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/b9fd59f95fc44b9c. Report an issue: GitHub.

Appendix: source

Thrown at application-answers.mjs:39

  for (const key of keys) {
    const value = object?.[key];
    if (Array.isArray(value)) {
      if (value.length > 0) return value;
      continue;
    }
    if (value !== undefined && value !== null && String(value).trim()) return value;
  }
  return '';
}

function list(value) {
  return Array.isArray(value) ? value : [];
}

function normalizeState(state) {
  const normalized = inline(state || 'filled').toLowerCase();
  if (!VALID_STATES.has(normalized)) {
    throw new Error(`Application answer state must be one of: ${[...VALID_STATES].join(', ')}`);
  }
  return normalized;
}

function normalizeDate(date) {
  return inline(date || new Date().toISOString().slice(0, 10));
}

function quoteBlock(value) {
  const text = String(value ?? '').replace(/\r\n/g, '\n').trim();
  if (!text) return '> Not recorded.';
  return text.split('\n').map((line) => `> ${line}`).join('\n');
}

function qaLines(entries, { labelKeys, valueKeys, fallback }) {
  if (entries.length === 0) return ['- None captured.'];

  return entries.flatMap((entry, index) => {

View on GitHub (pinned to aac998c7ed)