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

  1. Find and clean orphaned submissions: `Submission.where.missing(:assignment)` and remove or restore them
  2. Restore the deleted assignment or nullify/repoint the submission's association
  3. Guard handler scheduling at the caller so submissions without valid assignments are filtered out
  4. 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

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


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)