instructure/canvas-lms · error · PeerReview::InvalidParentAssignmentError
Invalid parent assignment
Error message
Invalid parent assignment
What it means
PeerReview::Validations#validate_parent_assignment raises PeerReview::InvalidParentAssignmentError when the assignment passed to a peer-review service is nil, not an Assignment instance, or not persisted to the database. Peer review sub-assignments must be attached to a real, saved parent assignment, so the library refuses to operate on unsaved or wrong-typed objects.
Solutions
- Save the assignment first and check `assignment.persisted?` before invoking peer review services.
- Verify you are passing the parent Assignment object, not nil or another model.
- In specs/tests, use a persisted factory-created assignment (create(:assignment)) rather than build(:assignment).
Example fix
// before sub_assignment = PeerReview::CreatorService.new(parent_assignment: assignment) # assignment was built but never saved // after assignment.save! raise "parent must be persisted" unless assignment.persisted? sub_assignment = PeerReview::CreatorService.new(parent_assignment: assignment)
Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, "parent assignment must be persisted" unless assignment.is_a?(Assignment) && assignment.persisted?
Type guard
def valid_parent_assignment?(a) = a.is_a?(Assignment) && a.persisted?
Try / catch
begin
service.call
rescue PeerReview::InvalidParentAssignmentError => e
Rails.logger.warn("peer review: #{e.message}")
render json: { error: e.message }, status: :unprocessable_entity
end Prevention
- Always save! the parent assignment before peer review operations
- Use create/factory-created records in tests, not build
- Never pass nil; fetch with find! so missing records fail early
When it happens
Trigger: Calling any peer review service that includes PeerReview::Validations with assignment = nil; passing a non-Assignment object (e.g. a sub-assignment or an Assignment clone); passing an Assignment built with Assignment.new but never saved (not persisted).
Common situations: Building an assignment in a controller and calling peer-review creation before `save` succeeds; refactoring code that now passes an Assignment object from a different namespace or a test double; a failed save returning an unsaved model that is then handed to the service.
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
- Due date cannot be before available from date
- Must be a group assignment to create group overrides
- Peer review sub assignment does not exist
- Peer review sub assignment exists
- Peer review sub assignments cannot have a not_graded…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/0cad7e76c03e7d2f.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/peer_review/validations.rb:23
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module PeerReview::Validations
def validate_parent_assignment(assignment)
unless assignment.present? && assignment.is_a?(Assignment) && assignment.persisted?
raise PeerReview::InvalidParentAssignmentError, I18n.t("Invalid parent assignment")
end
end
def validate_peer_reviews_enabled(assignment)
unless assignment.peer_reviews?
raise PeerReview::PeerReviewsNotEnabledError, I18n.t("Peer reviews are not enabled for this assignment")
end
end
def validate_feature_enabled(assignment)
unless assignment.context.feature_enabled?(:peer_review_allocation_and_grading)
raise PeerReview::FeatureDisabledError, I18n.t("Peer Review Allocation and Grading feature flag is disabled")
end
end
def validate_grading_type(grading_type)
raise PeerReview::InvalidGradingTypeError, I18n.t("Peer review sub assignments cannot have a not_graded grading type") if grading_type == "not_graded"
endView on GitHub (pinned to 1c9f0bb801)