Yeachan-Heo/oh-my-codex · error
${path} cardinality must match selected values
Error message
${path} cardinality must match selected values What it means
assertSelectedLabelsMatch requires selected_labels to have the same length as the labels expected from selected_values. A mismatch means the parallel arrays are inconsistent — one value has no corresponding label or vice versa.
Source
Thrown at src/question/state.ts:331
selectedValues: string[],
otherText: string | undefined,
): string[] {
const optionLabelsByValue = new Map(question.options.map((option) => [option.value, option.label]));
return selectedValues.map((value) => {
const optionLabel = optionLabelsByValue.get(value);
if (optionLabel) return optionLabel;
if (question.allow_other && otherText && value === otherText) return question.other_label;
throw new Error(`selected value is not in the option schema: ${value}`);
});
}
function assertSelectedLabelsMatch(
selectedLabels: string[],
expectedLabels: string[],
path: string,
): void {
if (selectedLabels.length !== expectedLabels.length) {
throw new Error(`${path} cardinality must match selected values`);
}
const mismatchIndex = selectedLabels.findIndex((label, index) => label !== expectedLabels[index]);
if (mismatchIndex !== -1) {
throw new Error(`${path}[${mismatchIndex}] must match the selected value label`);
}
}
function questionForAnswer(record: QuestionRecord, entry: QuestionAnswerEntry): NormalizedQuestionItem {
const question = (record.questions ?? []).find((item) => item.id === entry.question_id);
if (question) return question;
if (entry.question_id === 'q-1') {
return {
id: 'q-1',
...(record.header ? { header: record.header } : {}),
question: record.question,
options: record.options,
allow_other: record.allow_other,
other_label: record.other_label,View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Always derive selected_labels from selected_values via the question schema instead of maintaining them separately
- Validate lengths match right before submit
Example fix
// before answer.selected_values = ['a','b']; answer.selected_labels = ['Option A']; // after answer.selected_labels = answer.selected_values.map((v) => labelForValue(question, v));
Defensive patterns
Strategy: validation
Validate before calling
if (answer.selected_labels.length !== answer.selected_values.length) {
answer.selected_labels = answer.selected_values.map((v) => labelFor(question, v));
} Type guard
function labelsAligned(values: string[], labels: string[]): boolean { return values.length === labels.length; } Try / catch
try { await submit(p, answers); } catch (e) { if (/cardinality must match/.test((e as Error).message)) { rebuildLabelsFromSchema(); return submit(p, answers); } throw e; } Prevention
- Derive selected_labels from selected_values and the schema in one function
- Never filter the arrays independently
When it happens
Trigger: Submitting selected_values.length !== selected_labels.length, e.g. values ['a','b'] with labels ['Option A']; dropping a label when filtering values; appending a value without its label.
Common situations: Independent filtering of the two arrays client-side; partial updates that mutate one array only; hand-built payloads in scripts/tests.
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
- ${path}[${mismatchIndex}] must match the selected value labe
- ${path} must be a non-empty string array
- selected value is not in the option schema: ${value}
- answers[${entry.index}].question_id is unknown for this ques
- answers[${entry.index}].answer.kind=other is not allowed for
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/ffcedc21698890eb.
Report an issue: GitHub.