paperclipai/paperclip · error · PhotonAnswerValidationError
Choose valid option numbers without duplicates
Error message
Choose valid option numbers without duplicates
What it means
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.
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)
Example fix
// before
await answer(interaction, index, "1 1 9");
// after
const nums = [1, 3];
if (new Set(nums).size !== nums.length || nums.some(n => n < 1 || n > question.options.length)) return;
await answer(interaction, index, nums.join(" ")); Defensive patterns
Strategy: validation
Validate before calling
const nums = value.split(/[ ,]+/).map(Number); const ok = nums.every(n => n >= 1 && n <= question.options.length) && new Set(nums).size === nums.length;
Try / catch
try { return parsePhotonQuestionAnswer(interaction, i, value); } catch (e) { if (e instanceof PhotonAnswerValidationError && /valid option numbers/.test(e.message)) return re-renderOptions(question); throw e; } Prevention
- Show the live option list and validate numbers client-side
- Always 1-based numbering matching the rendered prompt
- Deduplicate user-supplied numbers before sending
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Answer with the option number(s) shown in the prompt
- Choose one option
- Write your custom answer as text
- A full lowercase source SHA is required.
- A reusable lease cannot be replaced and reacquired in the…
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/06719972b2d629b2.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/interactions.ts:103
if (question.required !== false)
throw new PhotonAnswerValidationError("This question requires an answer");
return { questionId: question.id, optionIds: [] };
}
if (!value || value.length > 100_000)
throw new PhotonAnswerValidationError(
"Enter a nonempty answer within the task’s length limit",
);
const numbers =
/^\d+(?:[ ,]+\d+)*$/.test(value) &&
question.options.some((option) => !option.freeText)
? value.split(/[ ,]+/).map(Number)
: null;
if (numbers) {
if (
new Set(numbers).size !== numbers.length ||
numbers.some((index) => index < 1 || index > question.options.length)
)
throw new PhotonAnswerValidationError(
"Choose valid option numbers without duplicates",
);
if (question.selectionMode === "single" && numbers.length !== 1)
throw new PhotonAnswerValidationError("Choose one option");
if (numbers.some((index) => question.options[index - 1].freeText))
throw new PhotonAnswerValidationError("Write your custom answer as text");
return {
questionId: question.id,
optionIds: numbers.map((index) => question.options[index - 1].id),
};
}
const freeText = question.options.find((option) => option.freeText);
if (question.options.length && question.allowOther === false && !freeText)
throw new PhotonAnswerValidationError(
"Answer with the option number(s) shown in the prompt",
);
return {
questionId: question.id,View on GitHub (pinned to 3f1d897a7c)