instructure/canvas-lms · error · DataFormatError
Database error ( )
Error message
Database error (%{err}) What it means
Outcomes::CsvImporter#run rescues ActiveRecord::StatementInvalid raised during parse_file (e.g. database constraint violations, invalid UTF-8 bytes rejected by the DB, or timeouts while inserting outcome batches) and re-raises it as DataFormatError with 'Database error (%{err})' embedding the DB error message. It maps low-level DB failures during CSV import into the importer's public error type.
Solutions
- Read the embedded %{err} message to identify the failing statement/constraint.
- Fix the offending rows (encoding, duplicates, value lengths) in the CSV and re-import.
- Validate the file is valid UTF-8 before import (iconv/encoding check) when the DB error mentions invalid byte sequences.
- Check DB logs and connectivity if the statement failure is infrastructural rather than data-driven.
Example fix
// before
File.read('outcomes.csv') # may contain invalid UTF-8
// after
content = File.read('outcomes.csv').force_encoding('UTF-8')
raise 'not UTF-8' unless content.valid_encoding? Defensive patterns
Strategy: try-catch
Validate before calling
content = File.read(path)
abort 'invalid encoding' unless content.force_encoding('UTF-8').valid_encoding? Type guard
def db_safe_csv?(path)
c = File.read(path).force_encoding('UTF-8')
c.valid_encoding?
end Try / catch
begin
importer.run
rescue Outcomes::CsvImporter::DataFormatError => e
logger.error("import db error: #{e.message}")
end Prevention
- Enforce UTF-8 encoding on CSV files before import.
- Keep values within DB column limits and unique-index constraints.
- Check DB error logs for the embedded %{err} detail on repeated failures.
When it happens
Trigger: An outcomes CSV import where a batch insert inside parse_file triggers ActiveRecord::StatementInvalid — bad data violating DB constraints, encoding the database refuses, or statement failures on very large batches.
Common situations: Importing CSVs with invalid UTF-8 into a UTF-8 database; duplicate keys on outcome unique indexes; overly long values exceeding column limits; DB connectivity/timeout issues during a long import.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- File has no data
- File has no outcomes data
- Invalid CSV File
- Cannot modify outcome from another context
- Cyclic reference detected when importing
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/3d39249dbaf70bfa.
Report an issue: GitHub.
Appendix: source
Thrown at lib/outcomes/csv_importer.rb:67
@import = import
@file = file
end
delegate :context, to: :@import
def run(&)
status = { progress: 0, errors: [] }
yield status
file_errors = []
begin
parse_file(&)
rescue CSV::MalformedCSVError
raise DataFormatError, I18n.t("Invalid CSV File")
rescue ParseError => e
raise DataFormatError, e.message
rescue ActiveRecord::StatementInvalid => e
raise DataFormatError, I18n.t("Database error (%{err})", err: e.message)
end
status = {
errors: file_errors,
progress: 100
}
yield status
end
def parse_file
headers = nil
total = file_line_count
raise ParseError, I18n.t("File has no data") if total < 1
separator = test_header_i18n
rows = CSV.new(@file, col_sep: separator).to_enum
rows.with_index(1).each_slice(BATCH_SIZE) do |batch|
headers ||= validate_headers(*batch.shift)
raise ParseError, I18n.t("File has no outcomes data") if batch.empty?View on GitHub (pinned to 1c9f0bb801)