instructure/canvas-lms · error · PeerReview::InvalidDatesError
Peer review override available from date cannot be before…
Error message
Peer review override available from date cannot be before parent override available from date
What it means
PeerReview::InvalidDatesError from the elsif branch of the child unlock_at check in validate_dates_within_parent_boundaries: when the parent has NO due_at, the peer review's available-from date must still not precede the parent's available-from date (override: 'Peer review override available from date cannot be before parent override available from date'; non-override wording at line 166). It guarantees peer reviews never open before the parent assignment itself is available.
Solutions
- Set the peer review unlock_at to a timestamp >= parent (override) unlock_at
- Or give the parent assignment/override a due_at that is <= the desired peer review unlock_at so the primary branch applies
- Or remove the peer review unlock_at entirely (nil) so it inherits availability
- Pre-validate with the fallback logic: if parent.due_at.nil? && parent.unlock_at > child.unlock_at, fix child dates
Example fix
// before
parent = assignment (no due_at, unlock_at: '2026-05-01T00:00:00Z')
peer_review_dates = { unlock_at: '2026-04-20T00:00:00Z' }
// after
peer_review_dates = { unlock_at: '2026-05-01T00:00:00Z' } Defensive patterns
Strategy: validation
Validate before calling
def review_opens_after_parent_opens?(parent, pr_dates) parent_due = parent.due_at floor = parent_due || parent.unlock_at return true if floor.nil? || pr_dates[:unlock_at].nil? floor <= Time.zone.parse(pr_dates[:unlock_at].to_s) end
Try / catch
begin
validator.validate_peer_review_dates_against_parent_assignment(pr_dates, assignment)
rescue PeerReview::InvalidDatesError => e
if e.message.include?('before assignment available from')
pr_dates[:unlock_at] = assignment.unlock_at
retry
end
raise
end Prevention
- Treat parent unlock_at as the earliest floor for any peer review date
- For assignments without a due date, floor against unlock_at explicitly
- Recompute peer review dates whenever parent availability changes
- Test override scenarios where due_at_overridden is false so the unlock fallback applies
When it happens
Trigger: Calling validate_dates_within_parent_boundaries (via validate_peer_review_dates_against_parent_assignment or validate_override_dates_against_parent_override) with parent_due_at nil/absent, parent unlock_at set, and child unlock_at strictly earlier than parent unlock_at.
Common situations: Assignments with only an until date configured; overrides where due_at is not overridden (due_at_overridden false → nil) so validation falls back to unlock comparison; bulk-imported peer review schedules that start on day one of the course.
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
- Parent override due date cannot be before parent override…
- Peer review due date cannot be before assignment due date
- Peer review override available from date cannot be before…
- Peer review override due date cannot be before parent…
- Peer review override due date cannot be before parent…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/afdb050d467eb725.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/peer_review/validations.rb:165
def validate_dates_within_parent_boundaries(child_dates:, parent_unlock_at:, parent_due_at:, parent_lock_at:, is_override: false)
child_unlock_at = parse_date(child_dates, :unlock_at)
child_due_at = parse_date(child_dates, :due_at)
child_lock_at = parse_date(child_dates, :lock_at)
# Validate: parent unlock_at <= parent due_at
if parent_unlock_at && parent_due_at && parent_unlock_at > parent_due_at
raise PeerReview::InvalidDatesError,
is_override ? I18n.t("Parent override due date cannot be before parent override available from date") : I18n.t("Assignment due date cannot be before assignment available from date")
end
# Validate: child unlock_at constraint
# If parent_due_at is present, validate: parent due_at <= child unlock_at
# Otherwise, fall back to: parent unlock_at <= child unlock_at
if parent_due_at && child_unlock_at && parent_due_at > child_unlock_at
raise PeerReview::InvalidDatesError,
is_override ? I18n.t("Peer review override available from date cannot be before parent override due date") : I18n.t("Peer review available from date cannot be before assignment due date")
elsif !parent_due_at && parent_unlock_at && child_unlock_at && parent_unlock_at > child_unlock_at
raise PeerReview::InvalidDatesError,
is_override ? I18n.t("Peer review override available from date cannot be before parent override available from date") : I18n.t("Peer review available from date cannot be before assignment available from date")
end
# Validate: parent unlock_at <= child due_at (for backward compatibility)
if parent_unlock_at && child_due_at && parent_unlock_at > child_due_at
raise PeerReview::InvalidDatesError,
is_override ? I18n.t("Peer review override due date cannot be before parent override available from date") : I18n.t("Peer review due date cannot be before assignment available from date")
end
# Validate: parent due_at <= child due_at
if parent_due_at && child_due_at && parent_due_at > child_due_at
raise PeerReview::InvalidDatesError,
is_override ? I18n.t("Peer review override due date cannot be before parent override due date") : I18n.t("Peer review due date cannot be before assignment due date")
end
# Validate: child due_at <= parent lock_at
if child_due_at && parent_lock_at && child_due_at > parent_lock_at
raise PeerReview::InvalidDatesError,View on GitHub (pinned to 1c9f0bb801)