instructure/canvas-lms · error · Checkpoints::NoCheckpointsFoundError
Checkpoints not found
Error message
Checkpoints not found
What it means
DiscussionCheckpointDeleterService#find_checkpoints loads @assignment.sub_assignments and raises NoCheckpointsFoundError if there are none. The deleter is meant to tear down checkpoint sub-assignments for a discussion with has_sub_assignments; if the assignment has no sub-assignments there is nothing to delete, indicating the assignment isn't checkpointed (anymore).
Solutions
- Check assignment.has_sub_assignments? (and sub_assignments.any?) before calling the deleter and treat no-op as success.
- Make the caller idempotent: rescue NoCheckpointsFoundError and skip.
- If data is inconsistent (has_sub_assignments true but no sub_assignments), repair by setting has_sub_assignments: false instead of deleting.
Example fix
// before Checkpoints::DiscussionCheckpointDeleterService.call(assignment: a) // after if a.has_sub_assignments? && a.sub_assignments.any? Checkpoints::DiscussionCheckpointDeleterService.call(assignment: a) end
Defensive patterns
Strategy: try-catch
Validate before calling
return :noop unless assignment.has_sub_assignments? && assignment.sub_assignments.any?
Try / catch
begin Checkpoints::DiscussionCheckpointDeleterService.call(assignment:) rescue Checkpoints::NoCheckpointsFoundError # already deleted or never checkpointed; treat as idempotent success end
Prevention
- Make delete operations idempotent by checking sub_assignments.any? first
- Keep has_sub_assignments in sync when sub_assignments change
- Guard UI delete buttons on the assignment actually having checkpoints
When it happens
Trigger: Calling the deleter on an assignment whose has_sub_assignments is false or whose sub_assignments were already removed (double delete), e.g. duplicate delete requests or deleting checkpoints on a regular (non-checkpoint) discussion.
Common situations: Idempotency issues where the UI fires delete twice and the second call fails; calling the deleter for a plain discussion topic; data migrations/fixups that cleared sub_assignments without updating has_sub_assignments.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Checkpoint '# ' not found
- discussion_checkpoints feature flag must be enabled
- each date must have a type specified ('everyone' or…
- Course does not exist
- # with sis id # didn't exist for # # .
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/5addb42720af706e.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/checkpoints/discussion_checkpoint_deleter_service.rb:48
checkpoints.each do |checkpoint|
checkpoint.active_assignment_overrides.destroy_all
end
@assignment.active_assignment_overrides.destroy_all
checkpoints.destroy_all
update_assignment_and_discussion
true
end
private
def find_checkpoints
checkpoints = @assignment.sub_assignments
raise Checkpoints::NoCheckpointsFoundError, "Checkpoints not found" unless checkpoints.any?
checkpoints
end
def update_assignment_and_discussion
@assignment.update!(has_sub_assignments: false)
@discussion_topic.update!(reply_to_entry_required_count: 0)
end
end
View on GitHub (pinned to 1c9f0bb801)