{"record":{"id":"9ec2436e5e54b9ef","repo":"paperclipai/paperclip","slug":"photon-question-index-is-invalid","errorCode":null,"errorMessage":"Photon question index is invalid","messagePattern":"Photon question index is invalid","errorType":"validation","errorClass":"PhotonAnswerValidationError","httpStatus":null,"severity":"error","filePath":"server/src/services/photon/interactions.ts","lineNumber":197,"sourceCode":"      existing.promptMessageGuid,\n    ])\n      await adapter.state.update<PhotonPromptReceipt>(\n        `prompt-message:${guid}`,\n        (current) => current ?? existing,\n      );\n    if (existing.pollMessageGuid)\n      await adapter.state.update<PhotonPromptReceipt>(\n        `poll-message:${existing.pollMessageGuid}`,\n        (current) => current ?? existing,\n      );\n    return existing;\n  }\n  const question =\n    interaction.kind === \"ask_user_questions\"\n      ? interaction.payload.questions[questionIndex]\n      : null;\n  if (interaction.kind === \"ask_user_questions\" && !question)\n    throw new PhotonAnswerValidationError(\"Photon question index is invalid\");\n  const reference = `${binding.reference}.${questionIndex + 1}`;\n  const title =\n    projectSafeChatPublicationText(\n      question?.prompt ??\n        (interaction as RequestConfirmationInteraction).payload.prompt,\n    ).trim() || \"Input needed\";\n  const choices = question\n    ? question.options.map((option) => ({\n        id: option.id,\n        label:\n          projectSafeChatPublicationText(option.label).trim() ||\n          `Choice ${question.options.indexOf(option) + 1}`,\n      }))\n    : [\n        {\n          id: \"accept\",\n          label: projectSafeChatPublicationText(\n            (interaction as RequestConfirmationInteraction).payload","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/photon/interactions.ts#L179-L215","documentation":"PhotonAnswerValidationError thrown from publishPhotonPrompt when the interaction is kind 'ask_user_questions' but the provided questionIndex has no matching question in payload.questions. Publishing a numbered sub-prompt requires a valid question index.","triggerScenarios":"Calling publishPhotonPrompt with questionIndex pointing past the end of (or before the start of) interaction.payload.questions for an ask_user_questions interaction.","commonSituations":"A loop over questions uses a stale count after the payload was trimmed; 1-based vs 0-based indexing bug; the question was removed between listing and publishing its prompt.","solutions":["Validate 0 <= questionIndex < interaction.payload.questions.length before calling publishPhotonPrompt","Iterate with interaction.payload.questions.map/forEach so the index is always in bounds","Refetch the interaction payload before publishing to avoid stale counts"],"exampleFix":"// before\nfor (let i = 0; i <= questions.length; i++) await publishPhotonPrompt(adapter, key, interaction, i);\n// after\nfor (let i = 0; i < interaction.payload.questions.length; i++) await publishPhotonPrompt(adapter, key, interaction, i);","handlingStrategy":"validation","validationCode":"const valid = interaction.kind === 'ask_user_questions' && Number.isInteger(questionIndex) && questionIndex >= 0 && questionIndex < interaction.payload.questions.length;","typeGuard":"const questionAt = (ia: PhotonInteraction, i: number) => ia.kind === 'ask_user_questions' ? ia.payload.questions[i] ?? null : null;","tryCatchPattern":"try { await publishPhotonPrompt(adapter, key, interaction, questionIndex); } catch (e) { if (e instanceof PhotonAnswerValidationError && /question index is invalid/.test(e.message)) return refetchInteraction(); throw e; }","preventionTips":["Iterate questions with forEach/map so indices stay in bounds","Refetch the interaction payload before publishing sub-prompts","Use 0-based indices consistently in publisher code"],"tags":["validation","index-out-of-bounds","publish"],"backgroundTag":"index-out-of-bounds","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"}