instructure/canvas-lms · error · PeerReview::InvalidDatesError
Parent override due date cannot be before parent override…
Error message
Parent override due date cannot be before parent override available from date
What it means
PeerReview::InvalidDatesError raised by validate_dates_within_parent_boundaries when the parent's own available-from date (unlock_at) is later than its due date. For overrides this reports 'Parent override due date cannot be before parent override available from date'; for the plain assignment path it reports the assignment wording. The parent's dates are checked first because child peer review dates are only meaningful relative to a coherent parent window.
Solutions
- Fix the parent assignment/override: set unlock_at <= due_at before creating the peer review
- Update the parent override record (AssignmentOverride unlock_at/due_at) so its window is ordered
- If the parent legitimately has no due date, clear due_at (nil) so only unlock constraints apply
- Pre-check parent dates in code: raise if parent.unlock_at && parent.due_at && parent.unlock_at > parent.due_at
Example fix
// before parent_override.update(unlock_at: '2026-05-10T00:00:00Z', due_at: '2026-05-01T00:00:00Z') create_peer_review_override(parent_override, ...) // after parent_override.update(unlock_at: '2026-05-01T00:00:00Z', due_at: '2026-05-10T00:00:00Z') create_peer_review_override(parent_override, ...)
Defensive patterns
Strategy: validation
Validate before calling
def parent_window_ordered?(parent) u, d = parent.unlock_at, parent.due_at !(u && d && u > d) end raise 'parent dates inverted' unless parent_window_ordered?(parent_override)
Try / catch
begin
create_peer_review_for(parent_override)
rescue PeerReview::InvalidDatesError => e
if e.message.include?('Parent override')
fix_parent_dates!(parent_override)
retry
end
raise
end Prevention
- Fix the parent assignment/override dates before configuring peer reviews
- Run assignment-level date validation before adding overrides or sub assignments
- Audit imported/seeded assignments for unlock_at > due_at
- Never assume the parent is valid just because peer review dates look right
When it happens
Trigger: Calling validate_override_dates_against_parent_override with a parent_override whose due_at_overridden date precedes its unlock_at_overridden date, or validate_peer_review_dates_against_parent_assignment with a parent assignment whose unlock_at > due_at — even if the peer review dates themselves are fine.
Common situations: Imported assignment overrides with inconsistent dates; a parent assignment edited to start later without moving its due date; seed/test fixtures with arbitrary dates; APIs accepting parent override updates without their own validation.
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
- Peer review due date cannot be before assignment due date
- Peer review override available from date cannot be before…
- 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/7571c2ca32059cbb.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/peer_review/validations.rb:154
parsed = Time.zone.parse(date_value)
if parsed.nil?
raise PeerReview::InvalidDatesError,
I18n.t("Invalid date format for %{field}: %{value}", field:, value: date_value)
end
parsed
else
date_value
end
end
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")View on GitHub (pinned to 1c9f0bb801)