{"record":{"id":"2ccb0fd5b4c82ce8","repo":"paperclipai/paperclip","slug":"answer-with-the-option-number-s-shown-in-the-prompt","errorCode":null,"errorMessage":"Answer with the option number(s) shown in the prompt","messagePattern":"Answer with the option number\\(s\\) shown in the prompt","errorType":"validation","errorClass":"PhotonAnswerValidationError","httpStatus":null,"severity":"error","filePath":"server/src/services/photon/interactions.ts","lineNumber":117,"sourceCode":"    if (\n      new Set(numbers).size !== numbers.length ||\n      numbers.some((index) => index < 1 || index > question.options.length)\n    )\n      throw new PhotonAnswerValidationError(\n        \"Choose valid option numbers without duplicates\",\n      );\n    if (question.selectionMode === \"single\" && numbers.length !== 1)\n      throw new PhotonAnswerValidationError(\"Choose one option\");\n    if (numbers.some((index) => question.options[index - 1].freeText))\n      throw new PhotonAnswerValidationError(\"Write your custom answer as text\");\n    return {\n      questionId: question.id,\n      optionIds: numbers.map((index) => question.options[index - 1].id),\n    };\n  }\n  const freeText = question.options.find((option) => option.freeText);\n  if (question.options.length && question.allowOther === false && !freeText)\n    throw new PhotonAnswerValidationError(\n      \"Answer with the option number(s) shown in the prompt\",\n    );\n  return {\n    questionId: question.id,\n    optionIds: freeText ? [freeText.id] : [],\n    otherText: value,\n  };\n}\nexport function photonAnswersMatch(\n  interaction: AskUserQuestionsInteraction,\n  result: unknown,\n): boolean {\n  if (!result || typeof result !== \"object\") return false;\n  const record = result as {\n    code?: unknown;\n    interactionId?: unknown;\n    answersSha256?: unknown;\n  };","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/interactions.ts#L99-L135","documentation":"PhotonAnswerValidationError thrown when the answer is free text but the question offers options, disallows free-form input (allowOther === false), and has no freeText option. In that case only option numbers are accepted.","triggerScenarios":"Calling parsePhotonQuestionAnswer with a non-numeric value on a question that has options.length > 0, allowOther === false, and no option with freeText: true.","commonSituations":"User ignores the numbered choices and types prose into a strict multiple-choice question; a UI renders an input box for a question that should be option-only; allowOther was tightened to false after the UI rendered.","solutions":["Resubmit using the option number(s) shown in the prompt","If free text should be allowed, set allowOther: true or add a freeText option and republish the prompt","Update the UI to hide free-input controls when allowOther is false and options exist"],"exampleFix":"// before\nawait answer(interaction, index, \"none of these\");\n// after\nif (question.allowOther === false && question.options.length) {\n  await answer(interaction, index, \"2\");\n} else {\n  await answer(interaction, index, \"none of these\");\n}","handlingStrategy":"validation","validationCode":"const freeTextAllowed = question.allowOther !== false || question.options.some(o => o.freeText); if (question.options.length && !freeTextAllowed && !/^\\d+([ ,]+\\d+)*$/.test(value)) throw new Error('option numbers required');","typeGuard":null,"tryCatchPattern":"try { return parsePhotonQuestionAnswer(interaction, i, value); } catch (e) { if (e instanceof PhotonAnswerValidationError && /option number/.test(e.message)) return forceOptionSelection(question); throw e; }","preventionTips":["Hide free-text inputs when allowOther === false and options exist","Check allowOther and freeText presence before accepting prose answers","Resurface the numbered prompt when the user submits disallowed text"],"tags":["validation","free-text-disallowed","option-selection"],"backgroundTag":"invalid-argument-format","analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}