instructure/canvas-lms · error
Submission must be at least 5 words long
Error message
Submission must be at least 5 words long
What it means
GradeService#validate_essay_length requires the (sanitized) essay to contain at least 5 words before sending it to the external Cedar AI grader. This minimum-length guard avoids wasting grading API calls on trivially short submissions. It runs during call(), after sanitize_essay.
Solutions
- Have the student resubmit with a longer response, or disable AI/essay grading for short-answer questions
- Guard in the caller: text.split.size >= 5 before constructing GradeService, showing a friendly message otherwise
- If legitimate short responses should be graded, lower the threshold or bypass GradeService for those items
Example fix
// before
GradeService.new(essay: submission.body, rubric:).call
// after
if submission.body.split.size < 5
return { error: I18n.t('Submission must be at least 5 words long') }
end
GradeService.new(essay: submission.body, rubric:).call Defensive patterns
Strategy: validation
Validate before calling
raise 'too short' if essay.to_s.split.size < 5
Type guard
essay.to_s.split.size >= 5
Try / catch
begin
GradeService.new(essay:, rubric:, rubric_association:).call
rescue RuntimeError => e
show_too_short_error if e.message.include?('at least 5 words')
end Prevention
- Enforce a client-side minimum word count on essay boxes
- Only enable AI grading for long-form questions
- Count words after sanitization, not before
When it happens
Trigger: Calling GradeService.call with an essay of fewer than 5 whitespace-separated words after sanitization; very short answers to an essay question on an assignment with AI grading enabled; a submission that shrinks below 5 words once tags/multiple spaces are stripped.
Common situations: Students submitting one-line answers to essay prompts; auto-graded practice assignments with AI grading enabled on short-answer questions; tests with stub essays shorter than 5 words.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Peer review sub assignments cannot have a not_graded…
- Rubric criteria not descriptive enough
- A course did not pass validation
- A # user did not pass validation (user: # , # : # , error…
- A maximum of 50 assessees can be provided at once
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/b953f98cb9615e64.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/grade_service.rb:158
.gsub(/<[^>]*>/, "") # Remove any remaining opening tags
.gsub(%r{</[^>]*>}, "") # Remove any remaining closing tags
# Remove any content between \< and \> (including the entities themselves)
text = text.gsub(%r{\\<[^&]*\\>.*?\\</[^&]*\\>}, "") # Remove content between encoded opening and closing tags
.gsub(/\\<[^&]*\\>/, "") # Remove any remaining encoded opening tags
.gsub(%r{\\</[^&]*\\>}, "") # Remove any remaining encoded closing tags
raise "No essay submission found after removing text between <>" if text.blank?
# Remove lines starting with more than 3 # characters
text = text.split("\n").reject { |line| line.strip.start_with?("####") }.join("\n")
# Clean up any resulting double spaces and trim
text.gsub(/\s+/, " ").strip
end
def validate_essay_length(text)
raise "Submission must be at least 5 words long" if text.split.size < 5
end
def friendly_cedar_error_for(error)
case error
when InstructureMiscPlugin::Extensions::CedarClient::CedarLimitReachedError
I18n.t("Grading is temporarily unavailable. Please try again later.")
when InstructureMiscPlugin::Extensions::CedarClient::ContentTooLongError
I18n.t("The submission is too long to be graded automatically.")
when InstructureMiscPlugin::Extensions::CedarClient::UnsupportedLanguageError
I18n.t("The submission language is not supported for automatic grading.")
else
I18n.t("An unexpected error occurred while grading.")
end
end
def rubric_matches_default_template?
predefined_criteria_templates = [
["Exit Ticket Prompt", "Preparation", "Time", "Participation"],View on GitHub (pinned to 1c9f0bb801)