instructure/canvas-lms · warning
No assignment present for submission #
Error message
No assignment present for submission #{id}; skipping conditional release handler What it means
When a submission's grade changes, Canvas enqueues a conditional release (rollout) grade change handler via its assignment. If the submission has no assignment associated (orphaned or deleted record), it logs this warning and skips the handler instead of raising a NoMethodError on nil.
Solutions
- Find and clean orphaned submissions: `Submission.where.missing(:assignment)` and remove or restore them
- Restore the deleted assignment or nullify/repoint the submission's association
- Guard handler scheduling at the caller so submissions without valid assignments are filtered out
- If orphaned data is unexpected, audit deletion callbacks to ensure submissions are destroyed with their assignment
Example fix
// before
if assignment.present? && assignment.queue_conditional_release_grade_change_handler?
queue_conditional_release_grade_change_handler
end
// after: filter early at the scope/caller level
scope :with_gradable_assignment, -> { joins(:assignment).merge(Assignment.active) }
# then only enqueue handlers for submissions in that scope Defensive patterns
Strategy: type-guard
Validate before calling
sub = Submission.find(id)
if sub.assignment.blank?
Rails.logger.warn("submission #{sub.id} has no assignment; skipping")
end Type guard
def gradeable_submission?(submission) submission.graded? && submission.posted? && submission.assignment.present? end
Prevention
- Destroy submissions together with their assignments (dependent: :destroy)
- Filter handler scheduling with joins(:assignment) so orphaned submissions are skipped
- Monitor logs for this warning as an orphaned-data signal and clean records
When it happens
Trigger: Running conditional-release grade-change callbacks on a Submission whose assignment_id is nil or whose assignment was hard-deleted while the submission survived, with graded?/posted? conditions met so the handler path is reached.
Common situations: Data cleanup deleted assignments without cascading submissions; cross-shard or import artifacts producing orphaned submissions; conditional release feature enabled while processing legacy/bad data.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- assessor and assessee required
- association required
- can only forward one conversation at a time
- can't accept
- Can't update submission scores unless it's completed
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/1d89e547fd7ad72f.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/submission.rb:2406
{ priority:, strand: },
self)
assignment&.delay_if_production(strand:)&.multiple_module_actions([user_id], :scored, score)
end
def maybe_queue_conditional_release_grade_change_handler
shard.activate do
if Account.site_admin.feature_enabled? :mastery_path_submission_trigger_reloaded_evaluation
reloaded = Submission.find(id)
return unless reloaded.graded? && reloaded.posted?
else
return unless graded? && posted?
end
if assignment.present? && assignment.queue_conditional_release_grade_change_handler?
queue_conditional_release_grade_change_handler
elsif assignment.blank?
logger.warn("No assignment present for submission #{id}; skipping conditional release handler")
end
end
end
scope :with_assignment, -> { joins(:assignment).merge(Assignment.active) }
scope :graded, -> { where("(submissions.score IS NOT NULL AND submissions.workflow_state = 'graded') or submissions.excused = true") }
scope :with_sticker, -> { where.not(sticker: nil) }
scope :not_submitted_or_graded, -> { where(submission_type: nil).where("(submissions.score IS NULL OR submissions.workflow_state <> 'graded') AND submissions.excused IS NOT TRUE") }
scope :ungraded, -> { where(grade: nil).preload(:assignment) }
scope :in_workflow_state, ->(provided_state) { where(workflow_state: provided_state) }
scope :having_submission, -> { where.not(submissions: { submission_type: nil }) }
scope :without_submission, -> { where(submission_type: nil, workflow_state: "unsubmitted") }
scope :not_placeholder, lambda {
active.where("submissions.submission_type IS NOT NULL or submissions.excused or submissions.score IS NOT NULL or submissions.workflow_state = 'graded'")View on GitHub (pinned to 1c9f0bb801)