{"record":{"id":"06719972b2d629b2","repo":"paperclipai/paperclip","slug":"choose-valid-option-numbers-without-duplicates","errorCode":null,"errorMessage":"Choose valid option numbers without duplicates","messagePattern":"Choose valid option numbers without duplicates","errorType":"validation","errorClass":"PhotonAnswerValidationError","httpStatus":null,"severity":"error","filePath":"server/src/services/photon/interactions.ts","lineNumber":103,"sourceCode":"    if (question.required !== false)\n      throw new PhotonAnswerValidationError(\"This question requires an answer\");\n    return { questionId: question.id, optionIds: [] };\n  }\n  if (!value || value.length > 100_000)\n    throw new PhotonAnswerValidationError(\n      \"Enter a nonempty answer within the task’s length limit\",\n    );\n  const numbers =\n    /^\\d+(?:[ ,]+\\d+)*$/.test(value) &&\n    question.options.some((option) => !option.freeText)\n      ? value.split(/[ ,]+/).map(Number)\n      : null;\n  if (numbers) {\n    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,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/interactions.ts#L85-L121","documentation":"PhotonAnswerValidationError thrown when the answer is parsed as option numbers but fails validation: numbers contain duplicates or fall outside the 1..questions.options.length range. Numeric answers are only interpreted as option selections when the question has at least one non-freeText option.","triggerScenarios":"Calling parsePhotonQuestionAnswer with numeric input like \"3 3\" (duplicate), \"0\" or \"7\" (out of range for the option count), for a question with non-freeText options.","commonSituations":"User types an option number that does not exist because the prompt was republished with fewer options; duplicated numbers from copy-paste; 0-based vs 1-based numbering confusion.","solutions":["Resubmit with valid, distinct numbers between 1 and question.options.length","Refetch the current interaction to see the live option list before answering","If the intent is free text, disable numeric interpretation by writing non-numeric text (subject to allowOther/freeText rules)"],"exampleFix":"// before\nawait answer(interaction, index, \"1 1 9\");\n// after\nconst nums = [1, 3];\nif (new Set(nums).size !== nums.length || nums.some(n => n < 1 || n > question.options.length)) return;\nawait answer(interaction, index, nums.join(\" \"));","handlingStrategy":"validation","validationCode":"const nums = value.split(/[ ,]+/).map(Number); const ok = nums.every(n => n >= 1 && n <= question.options.length) && new Set(nums).size === nums.length;","typeGuard":null,"tryCatchPattern":"try { return parsePhotonQuestionAnswer(interaction, i, value); } catch (e) { if (e instanceof PhotonAnswerValidationError && /valid option numbers/.test(e.message)) return re-renderOptions(question); throw e; }","preventionTips":["Show the live option list and validate numbers client-side","Always 1-based numbering matching the rendered prompt","Deduplicate user-supplied numbers before sending"],"tags":["validation","option-selection","index-out-of-range"],"backgroundTag":"invalid-argument-value","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"}