Yeachan-Heo/oh-my-codex · error

answers[${index}].answer must include selected_labels[] and

Error message

answers[${index}].answer must include selected_labels[] and selected_values[]

What it means

Thrown by normalizeSubmittedAnswers after kind validation passes. Every submitted answer must carry selected_labels and selected_values as actual arrays, since the renderer and result aggregation iterate both. If either is missing or not an array (e.g. a string or object), this error is raised with the offending index.

Source

Thrown at src/question/events.ts:228

  if (rawAnswers.length === 0) throw new Error('answer payload must include answer or answers[]');
  const validQuestionIds = new Set((record.questions ?? []).map((question) => question.id));
  if (validQuestionIds.size === 0) validQuestionIds.add('q-1');
  const seen = new Set<string>();

  return rawAnswers.map((entry, index) => {
    if (!entry || typeof entry !== 'object' || Array.isArray(entry)) throw new Error(`answers[${index}] must be an object`);
    const object = entry as Record<string, unknown>;
    const questionId = safeString(object.question_id) || (record.questions?.[index]?.id ?? (index === 0 ? 'q-1' : ''));
    if (!questionId || !validQuestionIds.has(questionId)) throw new Error(`answers[${index}].question_id is unknown for this question: ${questionId || '<missing>'}`);
    if (seen.has(questionId)) throw new Error(`answers question_id must be unique: ${questionId}`);
    seen.add(questionId);
    const answer = object.answer;
    if (!answer || typeof answer !== 'object' || Array.isArray(answer)) throw new Error(`answers[${index}].answer must be an object`);
    const answerObject = answer as Record<string, unknown>;
    const kind = safeString(answerObject.kind);
    if (!['option', 'other', 'multi'].includes(kind)) throw new Error(`answers[${index}].answer.kind must be option, other, or multi`);
    if (!Array.isArray(answerObject.selected_labels) || !Array.isArray(answerObject.selected_values)) {
      throw new Error(`answers[${index}].answer must include selected_labels[] and selected_values[]`);
    }
    return {
      question_id: questionId,
      index: Number.isInteger(object.index) ? object.index as number : index,
      answer: answerObject as unknown as QuestionAnswerEntry['answer'],
    };
  });
}

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Add both arrays: selected_labels: string[] and selected_values: string[].
  2. Wrap scalar selections in arrays (selected_values: ['yes'], not selected_values: 'yes').
  3. Run normalizeSubmittedAnswers on a sample payload during development to catch shape drift early.

Example fix

// before
answer: { kind: 'option', selected_values: 'yes' }

// after
answer: { kind: 'option', selected_labels: ['Yes'], selected_values: ['yes'] }
Defensive patterns

Strategy: validation

Validate before calling

const ok = answers.every((e, i) =>
  Array.isArray(e?.answer?.selected_labels) &&
  Array.isArray(e?.answer?.selected_values)
);

Type guard

function hasSelectionArrays(a: unknown): a is { selected_labels: string[]; selected_values: string[] } {
  const o = a as Record<string, unknown>;
  return Array.isArray(o?.selected_labels) && Array.isArray(o?.selected_values);
}

Try / catch

try { await result({ answers }); } catch (e) { if (e instanceof Error && /selected_labels\[\] and selected_values\[\]/.test(e.message)) { /* backfill missing arrays */ } else throw e; }

Prevention

When it happens

Trigger: Submitting answers[i].answer with kind 'option'/'other'/'multi' but omitting selected_labels or selected_values, or sending them as strings/objects (e.g. selected_labels: 'Yes' instead of ['Yes']).

Common situations: Minimal hand-written payloads that only include a value; clients that model single-select as a scalar instead of a one-element array; copying example JSON that predates the two-array schema.

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


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/fd7a61b33f06a96f. Report an issue: GitHub.