{"record":{"id":"3ccc3754ea010d78","repo":"instructure/canvas-lms","slug":"could-not-find-valid-question","errorCode":null,"errorMessage":"Could not find valid question","messagePattern":"Could not find valid question","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"app/models/quizzes/quiz_outcome_result_builder.rb","lineNumber":55,"sourceCode":"    end\n\n    private\n\n    def create_outcome_question_result(question, alignment)\n      # find or create the user's unique LearningOutcomeResult for this alignment\n      # of the quiz question.\n      quiz_result = alignment.learning_outcome_results\n                             .for_association(@qs.quiz)\n                             .for_associated_asset(@qs.quiz)\n                             .where(user_id: @qs.user.id)\n                             .first_or_initialize\n\n      quiz_result.workflow_state = :active\n      quiz_result.user_uuid = @qs.user.uuid\n\n      # get data from quiz submission's question result to ensure result should be generated\n      cached_question = @qs.quiz_data.detect { |q| q[:assessment_question_id] == question.id }\n      raise \"Could not find valid question\" unless cached_question\n\n      cached_answer = @qs.submission_data.detect { |q| q[:question_id] == cached_question[:id] }\n      raise \"Could not find valid answer\" unless cached_answer\n\n      # Create a question scoped outcome result linked to the quiz_result.\n      question_result = quiz_result.learning_outcome_question_results.for_associated_asset(question).first_or_initialize\n\n      # do not create a result if no points are possible.\n      if cached_question[\"points_possible\"] == 0\n        # destroy any existing results that might be persisted if points possible were not always 0\n        question_result.destroy if question_result.persisted?\n        return\n      end\n\n      # update the result with stuff from the quiz submission's question result\n      question_result.learning_outcome = quiz_result.learning_outcome\n\n      # mastery","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/quizzes/quiz_outcome_result_builder.rb#L37-L73","documentation":"Quizzes::QuizOutcomeResultBuilder#create_outcome_question_result looks up the question in the quiz submission's cached quiz_data (snapshotted at submission time) by assessment_question_id and raises if it cannot be found. This means the AssessmentQuestion being aligned to outcomes was not part of the quiz when the student took it, so no outcome result can be generated for it.","triggerScenarios":"build_outcome_results iterates aligned questions and calls create_outcome_question_result for a question whose assessment_question_id is absent from @qs.quiz_data — e.g. the question was deleted/replaced or re-generated (new assessment_question_id) after the student's submission was taken.","commonSituations":"Teacher edits the quiz and swaps the question bank/question after submissions exist; assessment question was migrated to a new bank changing its id; stale quiz_data from an older submission version; outcome alignment points to a question from a different quiz version.","solutions":["Verify the AssessmentQuestion id exists in the quiz submission's quiz_data for that student's submission","Check whether the quiz was edited/question regenerated after the submission; align outcomes against the question version the student actually saw","Skip gracefully instead of raising when the question is not in quiz_data (wrap in a find and next)","Re-score/rebuild the outcome results from a submission version whose quiz_data contains the question"],"exampleFix":"// before\nraise \"Could not find valid question\" unless cached_question\n// after\ncached_question = @qs.quiz_data.detect { |q| q[:assessment_question_id] == question.id }\nnext unless cached_question\n","handlingStrategy":"validation","validationCode":"next unless @qs.quiz_data&.any? { |q| q[:assessment_question_id] == question.id }","typeGuard":"find_cached = ->(qs, question) { qs.quiz_data.to_a.detect { |q| q[:assessment_question_id] == question.id } }","tryCatchPattern":"begin\n  builder.build_outcome_results(alignment, questions)\nrescue RuntimeError => e\n  Rails.logger.warn(\"skipping outcome results: #{e.message}\")\nend","preventionTips":["Lock quizzes (or freeze question versions) after submissions exist","When regenerating assessment questions, map old ids to new ids for outcome alignment","Process outcome results per submission version matching the alignment's version","Prefer skipping unmatched questions over raising in batch result generation"],"tags":["quizzes","outcomes","data-mismatch"],"backgroundTag":"record-not-found","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}