instructure/canvas-lms · error · RuntimeError
User required for assessing
Error message
User required for assessing
What it means
RubricAssociation#assess creates a rubric assessment and requires opts to include :user (the student being assessed), :assessor, :artifact, and an assessment_type inside opts[:assessment]. Canvas raises this RuntimeError when opts[:user] is missing, since the artifact/assessment must be tied to a person.
Solutions
- Pass opts[:user] (the assessed student) along with assessor and artifact in the assess call
- Derive user from the artifact, e.g. user: submission.user, before calling assess
- Add the remaining required opts too: :assessor, :artifact, and params[:assessment][:assessment_type] to avoid the following raises
Example fix
// before
assoc.assess(assessment: { assessment_type: "grading" }, assessor: teacher, artifact: submission)
// after
assoc.assess(user: submission.user, assessor: teacher, artifact: submission,
assessment: { assessment_type: "grading" }) Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, "user, assessor, artifact and assessment_type required" unless opts[:user] && opts[:assessor] && opts[:artifact] && opts.dig(:assessment, :assessment_type)
Type guard
def assessable_opts?(opts) = opts[:user].is_a?(User) && opts[:assessor].is_a?(User) && !opts[:artifact].nil? && opts.dig(:assessment, :assessment_type).present?
Try / catch
begin
assoc.assess(opts)
rescue RuntimeError => e
raise unless e.message.include?("required for assessing")
Rails.logger.error("invalid assess opts: #{opts.keys.inspect}")
end Prevention
- Build the full opts hash (user, assessor, artifact, assessment_type) in one place
- Derive user from artifact.user when unsure
- Unit-test assess callers with all required keys present
When it happens
Trigger: Calling association.assess(assessment: {...}, assessor: x, artifact: y) without opts[:user]; or user derived from an artifact that is nil.
Common situations: Custom rubric-assessment controllers or scripts that forget :user; peer-review automation where the submission's user cannot be resolved; old code paths using positional args against the new opts API.
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
- assessor and assessee required
- association required
- context required
- root_account_id required
- Artifact required for assessing
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/762bf6132d81bb00.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/rubric_association.rb:308
association_object.is_a?(Assignment) && purpose == "grading" && assessment_type == "grading"
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]]
endView on GitHub (pinned to 1c9f0bb801)