instructure/canvas-lms · error · PeerReview::StudentIdsNotInCourseError
Student ids are not in course
Error message
Student ids are not in course
What it means
PeerReview::StudentIdsNotInCourseError raised by validate_student_ids_in_course when the (non-blank-checked upstream) student_ids arrive blank — the ids supplied do not correspond to enrollments the validator can confirm in the course.
Solutions
- Verify each id is an enrolled student in the target course before calling
- Re-fetch the course's student roster and use those ids
- Check for course/shard mismatch causing enrollment lookups to return nothing
Example fix
// before ids = [451, 452] # ids from another course service.call(student_ids: ids) // after ids = course.students.where(id: [451, 452]).pluck(:id) raise ArgumentError, 'no valid students' if ids.empty? service.call(student_ids: ids)
Defensive patterns
Strategy: validation
Validate before calling
valid_ids = course.students.where(id: student_ids).pluck(:id) raise ArgumentError, 'no students from the list are enrolled in this course' if valid_ids.empty?
Try / catch
begin
service.call(student_ids:)
rescue PeerReview::StudentIdsNotInCourseError
render json: { error: 'Students must be enrolled in the course' }, status: :unprocessable_entity
end Prevention
- Derive student ids from course.students rather than trusting client input
- Re-resolve enrollments at call time; rosters change with SIS syncs
- Filter out non-student roles (observers, designers) before calling
When it happens
Trigger: Calling a peer review service where the resolved student id list is blank: ids from users not enrolled in the course, ids filtered out by visibility/permissions, or an empty resolution result passed onward.
Common situations: Students enrolled after the call's enrollment snapshot; ids from a different course's roster; observer/test-student ids used by mistake.
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
- Course does not exist
- each date must have a type specified ('everyone' or…
- invalid date type: #
- Invalid enrollment type: #
- Must be a group assignment to create group overrides
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/852b4900e52818ec.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/peer_review/validations.rb:221
raise PeerReview::OverrideNotFoundError, I18n.t("Override does not exist") unless override.present?
end
def validate_section_exists(section)
raise PeerReview::SectionNotFoundError, I18n.t("Section does not exist") unless section.present?
end
def validate_course_exists(course)
raise PeerReview::CourseNotFoundError, I18n.t("Course does not exist") unless course.present?
end
def validate_student_ids_required(student_ids)
if student_ids.nil? || student_ids == "" || student_ids.to_s.strip.empty? || (student_ids.is_a?(Array) && student_ids.empty?)
raise PeerReview::StudentIdsRequiredError, I18n.t("Student ids are required")
end
end
def validate_student_ids_in_course(student_ids)
raise PeerReview::StudentIdsNotInCourseError, I18n.t("Student ids are not in course") if student_ids.blank?
end
def validate_set_type_supported(set_type, services)
unless services.key?(set_type)
supported_types = services.keys.join(", ")
raise PeerReview::SetTypeNotSupportedError,
I18n.t("Set type '%{set_type}' is not supported. Supported types are: %{supported_types}", set_type:, supported_types:)
end
end
def validate_group_assignment_required(assignment)
unless assignment.group_category_id
raise PeerReview::GroupAssignmentRequiredError, I18n.t("Must be a group assignment to create group overrides")
end
end
def validate_group_exists(group)
raise PeerReview::GroupNotFoundError, I18n.t("Group does not exist") unless group.present?View on GitHub (pinned to 1c9f0bb801)