instructure/canvas-lms · error · DataFormatError
The file is empty or does not contain valid rubric data.
Error message
The file is empty or does not contain valid rubric data.
What it means
RubricImport#process_rubrics raises DataFormatError when RubricCSVImporter.parse returns an empty hash — the uploaded rubric CSV contained no importable rows (empty file, headers only, or content the importer could not map).
Solutions
- Use the provided rubric CSV template and keep the exact header names ('Rubric Name', criteria, ratings columns)
- Re-save the spreadsheet as comma-separated CSV (UTF-8) and confirm rows exist below the header
- Ensure the uploaded file is the rubric CSV, not the assessment CSV or another export
- Open the CSV in a text editor to verify it has data rows and correct comma delimiters
Example fix
// before # file contains only: Rubric Name,Criteria,Ratings // after Rubric Name,Criteria,Ratings Essay Rubric,Quality,"Great:10,Good:7" Essay Rubric,Accuracy,"Perfect:10,Fair:5"
Defensive patterns
Strategy: validation
Validate before calling
csv = CSV.read(uploaded_path, headers: true)
raise "no rubric rows" if csv.empty?
raise "missing 'Rubric Name' column" unless csv.headers.include?("Rubric Name") Try / catch
begin import.process rescue DataFormatError => e flash[:error] = e.message end
Prevention
- Use the official rubric CSV template without renaming headers
- Ensure at least one fully populated data row exists
- Save as comma-separated UTF-8 CSV, not xlsx
- Verify in a text editor that rows and delimiters look correct
When it happens
Trigger: Uploading an empty file, a headers-only CSV, a wrongly formatted rubric CSV (unexpected columns so nothing parses), or the wrong file entirely (e.g. the assessments CSV instead of the rubric CSV).
Common situations: Spreadsheet export of the wrong sheet; CSV saved with wrong delimiter or encoding; template columns renamed; uploading a blank template without filling it in; file uploaded as .csv but actually xlsx content.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Missing 'Rubric Name' in some rows.
- The file is empty or does not contain valid assessment data.
- Friendly description is too long (maximum is 255 characters)
- Invalid fields after ratings
- Invalid fields
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/216904932115529a.
Report an issue: GitHub.
Appendix: source
Thrown at app/models/rubric_import.rb:104
ErrorReport.log_exception("rubrics_import_data_format", e)
update!(error_count: 1, error_data: [{ message: e.message }])
track_error
job_failed!
rescue CSV::MalformedCSVError => e
ErrorReport.log_exception("rubrics_import_csv", e)
update!(error_count: 1, error_data: [{ message: I18n.t("The file is not a valid CSV file."), exception: e.message }])
track_error
rescue => e
ErrorReport.log_exception("rubrics_import", e)
update!(error_count: 1, error_data: [{ message: I18n.t("An error occurred while importing rubrics."), exception: e.message }])
track_error
job_failed!
end
end
def process_rubrics
rubrics_by_name = RubricCSVImporter.new(attachment).parse
raise DataFormatError, I18n.t("The file is empty or does not contain valid rubric data.") if rubrics_by_name.empty?
total_rubrics = rubrics_by_name.keys.count
error_data = []
rubrics_by_name.each_with_index do |(rubric_name, rubric_data), rubric_index|
raise DataFormatError, I18n.t("Missing 'Rubric Name' in some rows.") if rubric_name.blank?
rubric = context.rubrics.build(rubric_imports_id: id)
criteria_hash = {}
rubric_data.each_with_index do |criterion, criterion_index|
raise DataFormatError, "Missing 'Criteria Name' for #{rubric_name}" if criterion[:description].blank?
raise DataFormatError, "Missing ratings for #{criterion[:description]}" if criterion[:ratings].empty?
ratings_hash = {}
criterion[:ratings].each_with_index do |rating, rating_index|
ratings_hash[rating_index.to_s] = {
"description" => rating[:description],
"long_description" => rating[:long_description],View on GitHub (pinned to 1c9f0bb801)