{"record":{"id":"502f28f86994930e","repo":"instructure/canvas-lms","slug":"course-does-not-exist","errorCode":null,"errorMessage":"Course does not exist","messagePattern":"Course does not exist","errorType":"validation","errorClass":"PeerReview::CourseNotFoundError","httpStatus":null,"severity":"error","filePath":"app/services/peer_review/validations.rb","lineNumber":211,"sourceCode":"\n  def validate_set_type_required(set_type)\n    raise PeerReview::SetTypeRequiredError, I18n.t(\"Set type is required\") unless set_type.present?\n  end\n\n  def validate_set_id_required(set_id)\n    raise PeerReview::SetIdRequiredError, I18n.t(\"Set id is required\") unless set_id.present?\n  end\n\n  def validate_override_exists(override)\n    raise PeerReview::OverrideNotFoundError, I18n.t(\"Override does not exist\") unless override.present?\n  end\n\n  def validate_section_exists(section)\n    raise PeerReview::SectionNotFoundError, I18n.t(\"Section does not exist\") unless section.present?\n  end\n\n  def validate_course_exists(course)\n    raise PeerReview::CourseNotFoundError, I18n.t(\"Course does not exist\") unless course.present?\n  end\n\n  def validate_student_ids_required(student_ids)\n    if student_ids.nil? || student_ids == \"\" || student_ids.to_s.strip.empty? || (student_ids.is_a?(Array) && student_ids.empty?)\n      raise PeerReview::StudentIdsRequiredError, I18n.t(\"Student ids are required\")\n    end\n  end\n\n  def validate_student_ids_in_course(student_ids)\n    raise PeerReview::StudentIdsNotInCourseError, I18n.t(\"Student ids are not in course\") if student_ids.blank?\n  end\n\n  def validate_set_type_supported(set_type, services)\n    unless services.key?(set_type)\n      supported_types = services.keys.join(\", \")\n      raise PeerReview::SetTypeNotSupportedError,\n            I18n.t(\"Set type '%{set_type}' is not supported. Supported types are: %{supported_types}\", set_type:, supported_types:)\n    end","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/peer_review/validations.rb#L193-L229","documentation":"PeerReview::CourseNotFoundError raised by validate_course_exists when the Course object is nil/not present. Nearly every peer review service depends on a valid course to scope lookups and permissions.","triggerScenarios":"Calling any peer review service with a course id that resolves to nil: nonexistent course id, course on another shard, deleted course, or lookup without the proper account/rootscope.","commonSituations":"Using the wrong id field (course.id vs context id 'course_123'); multi-shard lookup not going through the correct shard; course deleted before the job runs.","solutions":["Load the course via Course.find/courses scoped to the correct shard and confirm it exists","Parse the context id correctly (strip 'course_' prefix) before lookup","Check the course was not deleted and the API consumer uses a valid course id"],"exampleFix":"// before\ncourse = Course.find_by(id: 'course_123'.to_i) # nil -> raises\n// after\ncourse = Course.active.find(context_id.sub(/\\Acourse_/, ''))\nservice.call(course: course)","handlingStrategy":"type-guard","validationCode":"course = Course.find_by(id: course_id)\nraise ArgumentError, 'course not found' unless course","typeGuard":"course = context.is_a?(Course) ? context : Course.find_by(id: context.to_s.sub(/\\Acourse_/, '').to_i)","tryCatchPattern":"begin\n  service.call(course:)\nrescue PeerReview::CourseNotFoundError\n  head :not_found\nend","preventionTips":["Normalize 'course_123' context ids to integer ids before lookup","Load courses within the correct shard/account scope","Check course existence early in controllers with a before_action"],"tags":["ruby","peer-review","not-found","course","canvas"],"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"}