instructure/canvas-lms · error · RuntimeError

Assessor required for assessing

Error message

Assessor required for assessing

What it means

RubricAssociation#assess requires the caller to supply a hash of options including :user, :assessor, :artifact, and the assessment params. This guard fires when opts[:assessor] is nil/absent, meaning Canvas cannot record who performed the rubric assessment. It is a fail-fast contract check before any assessment rows are created.

Solutions

  1. Pass opts[:assessor] with the User (or user object) performing the assessment: ra.assess(user: student, assessor: teacher, artifact: submission, assessment: {assessment_type: 'grading'})
  2. Verify the assessor is resolved before calling assess (e.g. assessor = User.find(teacher_id); raise early with a friendlier message if nil)
  3. If integrating via the Submissions/Assessments API, confirm the endpoint supplies the assessor (the current user) rather than only the student

Example fix

// before
rubric_association.assess(
  user: student,
  artifact: submission,
  assessment: { assessment_type: 'grading', ... }
)
// after
rubric_association.assess(
  user: student,
  assessor: current_user,
  artifact: submission,
  assessment: { assessment_type: 'grading', ... }
)
Defensive patterns

Strategy: validation

Validate before calling

raise 'assessor required' unless opts[:assessor]
rubric_association.assess(user:, assessor:, artifact:, assessment:)

Type guard

valid = opts[:assessor].is_a?(User)

Try / catch

begin
  rubric_association.assess(opts)
rescue RuntimeError => e
  handle_missing_assessor if e.message == 'Assessor required for assessing'
end

Prevention

When it happens

Trigger: Calling rubric_association.assess(user:, artifact:, assessment: {...}) without opts[:assessor]; callers building the assess params hash programmatically (e.g. from an API request or LTI tool) and omitting the assessor id; assessor object resolved to nil because the supplied user id does not map to a real user with grading rights.

Common situations: Custom integrations or scripts that call assess directly and copy the wrong param key (e.g. :assessor_id instead of :assessor); third-party rubric tools passing incomplete params; refactors that removed the assessor lookup but left the assess call in place.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/c761143bd2326bd4. Report an issue: GitHub.

Appendix: source

Thrown at app/models/rubric_association.rb:309

  end

  def assessment_points(criterion, data)
    if criterion.learning_outcome_id && !context.feature_enabled?(:outcome_extra_credit)
      [criterion.points, data[:points].to_f].min
    else
      data[:points].to_f
    end
  end
  protected :assessment_points

  def assess(opts = {})
    # TODO: what if this is for a group assignment?  Seems like it should
    # give all students for the group assignment the same rubric assessment
    # results.
    association = self
    params = opts[:assessment]
    raise "User required for assessing" unless opts[:user]
    raise "Assessor required for assessing" unless opts[:assessor]
    raise "Artifact required for assessing" unless opts[:artifact]
    raise "Assessment type required for assessing" unless params[:assessment_type]

    if opts[:artifact].is_a?(Quizzes::QuizSubmission)
      opts[:artifact] = association_object.find_or_create_submission(opts[:artifact].user)
    end

    if association_object.is_a?(Assignment) && !association_object.grade_group_students_individually
      group, students_to_assess = association_object.group_students(opts[:artifact].student)
      if group
        provisional_grader = opts[:artifact].is_a?(ModeratedGrading::ProvisionalGrade) && opts[:assessor]
        artifacts_to_assess = students_to_assess.map do |student|
          association_object.find_asset_for_assessment(self, student, provisional_grader:).first
        end
      else
        artifacts_to_assess = [opts[:artifact]]
      end
    else

View on GitHub (pinned to 1c9f0bb801)