instructure/canvas-lms · error · CedarAi::Errors::GraderError
An unexpected error occurred while grading.
Error message
An unexpected error occurred while grading.
What it means
The final rescue in GradeService#call catches every non-Cedar exception (bugs, DB errors, nil rubric data, etc.), logs '[GradeService] Unexpected error: ...', and re-raises CedarAi::Errors::GraderError with the fixed user-safe message 'An unexpected error occurred while grading.' It deliberately hides internal details from end users.
Solutions
- Search server logs for '[GradeService] Unexpected error: <Class>' to find the real root cause.
- Validate rubric_data shape before calling the service (each criterion has :description and criteria ratings).
- Fix the underlying bug (nil guards, data normalization) rather than treating the generic message.
- Retry the grading job after correcting the input data.
Example fix
# before service.call(rubric_data: nil) # after raise ArgumentError, 'rubric_data is required' if rubric_data.blank? service.call(rubric_data: rubric_data)
Defensive patterns
Strategy: try-catch
Validate before calling
raise ArgumentError, 'rubric_data must be an array of criteria' unless rubric_data.is_a?(Array) && rubric_data.all? { |c| c[:description].present? } Try / catch
begin
GradeService.call(...)
rescue CedarAi::Errors::GraderError => e
if e.message == 'An unexpected error occurred while grading.'
check_server_logs_for_root_cause
end
end Prevention
- Validate rubric_data shape (non-nil, criteria with :description) before calling
- Guard against nil submissions/rubrics upstream of GradeService
- Treat this generic message as a signal to grep server logs for the real exception
- Add integration tests covering malformed rubric data
When it happens
Trigger: Any unexpected exception inside the grading flow: nil/malformed rubric_data passed to normalize_rubric_for_prompt, DB errors saving grades, NoMethodError from unexpected submission shape, I18n/translation issues — anything not a CedarClientError.
Common situations: Rubric data with unexpected structure (missing :description keys), nil rubric passed in, database constraint failures while persisting grades, code regressions after a Cedar integration change.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- friendly_cedar_error_for(e)
- A new_id, '# ', referenced an existing # and the # with #…
- A new_integration_id, '#
- A student referenced a non-existent user #
- A user did not pass validation
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/f049e1c00e817b0e.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/grade_service.rb:64
feature_slug: "grading-assistance",
root_account_uuid: @root_account_uuid,
current_user: @current_user
)
map_grade_essay_results_to_canvas(grading_results, @rubric)
# These subclasses have static, user-safe messages and can be shown directly.
# If new CedarClientError subclasses are added with user-safe messages, add them here.
rescue InstructureMiscPlugin::Extensions::CedarClient::ValidationError,
InstructureMiscPlugin::Extensions::CedarClient::CedarLimitReachedError,
InstructureMiscPlugin::Extensions::CedarClient::UnsupportedLanguageError,
InstructureMiscPlugin::Extensions::CedarClient::ContentTooLongError => e
raise CedarAi::Errors::GraderError, friendly_cedar_error_for(e)
rescue InstructureMiscPlugin::Extensions::CedarClient::CedarClientError => e
Rails.logger.error("[GradeService] Cedar API error: #{e.message}")
raise CedarAi::Errors::GraderError, friendly_cedar_error_for(e)
rescue => e
Rails.logger.error("[GradeService] Unexpected error: #{e.class}: #{e.message}")
raise CedarAi::Errors::GraderError, I18n.t("An unexpected error occurred while grading.")
end
end
def self.normalize_rubric_for_prompt(rubric_data)
rubric_data.each_with_object({}) do |criterion, acc|
key = criterion[:description]
acc[key] = {
"Criteria" => (criterion[:ratings] || []).map do |rating|
{
"Description" => rating_description_for(criterion, rating),
"Points" => rating[:points]
}
end,
"MaximumPoints" => criterion[:points]
}
end
end
View on GitHub (pinned to 1c9f0bb801)