paperclipai/paperclip · error · PhotonAnswerValidationError
Write your custom answer as text
Error message
Write your custom answer as text
What it means
PhotonAnswerValidationError thrown when the numeric answer selects an option whose freeText flag is true. Free-text options are not selectable by number — a custom answer must be submitted as plain text, not as an option index.
Solutions
- Submit the custom answer as plain text instead of the freeText option's number
- Filter out freeText options when rendering selectable numbered options
- Combine the option selection only over non-freeText options
Example fix
// before await answer(interaction, index, String(question.options.length)); // the "Other" option // after await answer(interaction, index, "my custom answer");
Defensive patterns
Strategy: validation
Validate before calling
const selectable = question.options.map((o, idx) => ({ o, idx })).filter(x => !x.o.freeText); if (selectedNumbers.some(n => question.options[n-1]?.freeText)) throw new Error('free-text option not selectable by number'); Type guard
const isFreeTextOption = (o: { freeText?: boolean }) => o.freeText === true; Try / catch
try { return parsePhotonQuestionAnswer(interaction, i, value); } catch (e) { if (e instanceof PhotonAnswerValidationError && /custom answer as text/.test(e.message)) return submitFreeText(value); throw e; } Prevention
- Exclude freeText options from numbered selectable lists
- Route 'Other' selections into a text input instead of an index
- Submit custom answers as plain text
When it happens
Trigger: Calling parsePhotonQuestionAnswer with a number pointing at the freeText option (e.g. the last "Other…" option) instead of providing the custom text directly.
Common situations: UI shows the free-text "Other" option numbered in the list and the user picks it by number; an agent enumerates all options including the freeText one.
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
- Choose valid option numbers without duplicates
- 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/413b7edb918717bc.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/photon/interactions.ts:109
"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,
optionIds: freeText ? [freeText.id] : [],
otherText: value,
};
}
export function photonAnswersMatch(
interaction: AskUserQuestionsInteraction,View on GitHub (pinned to 3f1d897a7c)