{"record":{"id":"6e01569cd536042b","repo":"Yeachan-Heo/oh-my-codex","slug":"answers-entry-index-answer-kind-other-is-only","errorCode":null,"errorMessage":"answers[${entry.index}].answer.kind=other is only valid for single-answerable questions","messagePattern":"answers\\[(.+?)\\]\\.answer\\.kind=other is only valid for single-answerable questions","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/question/state.ts","lineNumber":371,"sourceCode":"  }\n  throw new Error(`answers[${entry.index}].question_id is unknown for this question: ${entry.question_id}`);\n}\n\nfunction validateAnswerAgainstQuestion(question: NormalizedQuestionItem, entry: QuestionAnswerEntry): void {\n  const { answer } = entry;\n  const selectedValues = validateStringArray(answer.selected_values, `answers[${entry.index}].answer.selected_values`);\n  const selectedLabels = validateStringArray(answer.selected_labels, `answers[${entry.index}].answer.selected_labels`);\n  assertNoDuplicateValues(selectedValues, `answers[${entry.index}].answer.selected_values`);\n\n  const optionValues = new Set(question.options.map((option) => option.value));\n  const multi = isMultiAnswerableQuestion(question);\n  const hasOtherText = typeof answer.other_text === 'string' && answer.other_text.trim().length > 0;\n  const otherText = hasOtherText ? answer.other_text!.trim() : undefined;\n  const outOfSchemaValues = selectedValues.filter((value) => !optionValues.has(value));\n\n  if (answer.kind === 'other') {\n    if (!question.allow_other) throw new Error(`answers[${entry.index}].answer.kind=other is not allowed for this question`);\n    if (multi) throw new Error(`answers[${entry.index}].answer.kind=other is only valid for single-answerable questions`);\n    if (!otherText) throw new Error(`answers[${entry.index}].answer.other_text must be a non-empty string`);\n    if (selectedValues.length !== 1 || selectedValues[0] !== otherText || answer.value !== otherText) {\n      throw new Error(`answers[${entry.index}].answer other value must match selected_values[0] and other_text`);\n    }\n    assertSelectedLabelsMatch(\n      selectedLabels,\n      [question.other_label],\n      `answers[${entry.index}].answer.selected_labels`,\n    );\n    return;\n  }\n\n  if (answer.kind === 'option') {\n    if (multi) throw new Error(`answers[${entry.index}].answer.kind=option is only valid for single-answerable questions`);\n    if (selectedValues.length !== 1 || selectedLabels.length !== 1) {\n      throw new Error(`answers[${entry.index}].answer must select exactly one option`);\n    }\n    const selectedValue = selectedValues[0]!;","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/question/state.ts#L353-L389","documentation":"kind 'other' is defined only for single-answerable questions. Submitting it for a multi-answerable question (multi_select) is rejected because multi answers with out-of-schema values are handled differently (values mixed with option values, not via kind).","triggerScenarios":"answer.kind === 'other' on a question where isMultiAnswerableQuestion(question) is true (multi_select set).","commonSituations":"Shared client submit path that always uses kind 'other' for free text regardless of question type; schema flipped from single to multi_select.","solutions":["For multi questions, include the free-text value inside selected_values (with other_text set) instead of using kind 'other'","Branch submit logic on question.multi_select"],"exampleFix":"// before\nif (freeText) answer.kind = 'other';\n// after\nif (freeText && question.multi_select) { answer.kind = 'multi'; answer.selected_values = [...picked, freeText]; answer.other_text = freeText; }\nelse if (freeText) answer.kind = 'other';","handlingStrategy":"type-guard","validationCode":"if (answer.kind === 'other' && isMulti(question)) throw new Error('use kind=multi with other_text for multi questions');","typeGuard":"function isMulti(q: NormalizedQuestionItem): boolean { return !!q.multi_select; }","tryCatchPattern":"try { await submit(p, answers); } catch (e) { if (/kind=other is only valid for single-answerable/.test((e as Error).message)) { convertOtherToMultiWithOtherText(answer); return submit(p, answers); } throw e; }","preventionTips":["Branch answer.kind on question.multi_select","For multi + free text, put other_text inside the multi payload"],"tags":["validation","multi-select","allow-other"],"backgroundTag":"schema-validation-failed","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}