instructure/canvas-lms · error
Couldn't convert QTI 1.2 to 2.1, see error log: #
Error message
Couldn't convert QTI 1.2 to 2.1, see error log: #{qti_error_file} What it means
Canvas quiz_converter shells out to a Python QTI conversion utility; run_qti_converter checks $?.exitstatus after the subprocess. A non-zero exit means QTI 1.2 could not be upgraded to QTI 2.1, and the converter raises with the path to the log file where the converter's stdout/stderr was written.
Solutions
- Open the qti_conversion_error.log path given in the message and fix the QTI XML issue it reports
- Validate/repair the QTI package with an external QTI validator before importing
- Confirm the python QTI converter and its dependencies are installed and runnable in the environment
- Convert the QTI to 2.1 yourself ahead of time (e.g. via a prep step) so the 1.2->2.1 conversion path is not needed
Example fix
// before
# importing a broken qti.zip directly
// after
# pre-validate in a wrapper script
unless system('qti_validator', 'quiz.zip')
puts 'fix QTI per validator output before import'
end Defensive patterns
Strategy: try-catch
Validate before calling
# pre-check QTI validity before import raise 'invalid QTI' unless File.exist?(manifest) && xml_valid?(manifest)
Try / catch
begin
converter.convert_quizzes
rescue RuntimeError => e
raise unless e.message.start_with?("Couldn't convert QTI 1.2 to 2.1")
log_file = e.message[/error log: (.+)$/, 1]
Rails.logger.error(File.read(log_file)) if log_file
end Prevention
- Validate QTI packages before import
- Keep the python QTI converter and its dependencies installed
- Test imports from each source LMS before bulk migration
When it happens
Trigger: Importing a quiz package with malformed or unsupported QTI 1.2 XML; the python converter exits non-zero, python_std_out is dumped to <base_export_dir>/qti_conversion_error.log, and the raise fires from run_qti_converter (invoked via convert_quizzes during course import).
Common situations: Migration imports of quizzes exported by other LMSs or old Canvas exports with QTI quirks; missing/incompatible python QTI converter dependencies in the environment; hand-crafted QTI packages with schema violations.
Related errors
- Can't export QTI without the python converter tool…
- Cannot validate existence for resource type: #
- Couldn't find QTI Migration Tool. See…
- course hasn't been converted
- Course not found
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/0fb049babd8916be.
Report an issue: GitHub.
Appendix: source
Thrown at lib/cc/importer/canvas/quiz_converter.rb:54
assessments
end
def run_qti_converter(qti_folder)
# convert to 2.1
@dest_dir_2_1 = File.join(qti_folder, "qti_2_1")
return unless File.exist?(qti_folder)
command = Qti.get_conversion_command(@dest_dir_2_1, qti_folder)
logger.debug "Running migration command: #{command}"
python_std_out = `#{command}`
if $?.exitstatus == 0
@converted = true
else
make_export_dir
qti_error_file = File.join(@base_export_dir, "qti_conversion_error.log")
File.open(qti_error_file, "w") { |f| f << python_std_out }
raise "Couldn't convert QTI 1.2 to 2.1, see error log: #{qti_error_file}"
end
end
def convert_questions
raise "The QTI must be converted to 2.1 before converting to JSON" unless @converted
questions = {}
begin
manifest_file = File.join(@dest_dir_2_1, Qti::Converter::MANIFEST_FILE)
questions[:assessment_questions] = Qti.convert_questions(manifest_file, flavor: Qti::Flavors::CANVAS)
rescue
questions[:qti_error] = "#{$!}: #{$!.backtrace.join("\n")}"
end
questions
end
def convert_assessments
raise "The QTI must be converted to 2.1 before converting to JSON" unless @convertedView on GitHub (pinned to 1c9f0bb801)