instructure/canvas-lms · error
Can't export QTI without the python converter tool…
Error message
Can't export QTI without the python converter tool installed.
What it means
QtiWorker#perform requires the :qti_converter Canvas plugin to exist and be enabled; that plugin is only enabled when the python QTI converter tool is installed and configured. Without it, QTI export content migrations cannot run and the worker raises immediately after starting the job progress.
Solutions
- Install the python QTI converter tool on the host running the migration job.
- Enable the qti_converter plugin (Account > Plugins > QTI Converter) and verify plugin.settings[:enabled].
- Verify the plugin configuration (paths/settings for the converter binary) and that the job process can execute it.
- If the converter cannot be installed, use a different export format instead of QTI.
Example fix
// before (shell on app host) # python converter not installed -> export fails // after sudo pip install the canvas qti converter tool # or distro package # then in UI: Admin > Plugins > QTI Converter > Enable
Defensive patterns
Strategy: validation
Validate before calling
plugin = Canvas::Plugin.find(:qti_converter) return :disabled unless plugin && plugin.settings[:enabled]
Try / catch
begin
worker.perform(migration_id, cm)
rescue RuntimeError => e
raise unless e.message.include?("Can't export QTI without the python converter tool")
cm.workflow_state = 'failed' # surface actionable error to the user
cm.save!
end Prevention
- Install the python QTI converter as part of base infrastructure provisioning.
- Assert plugin enabled-ness in smoke tests before offering QTI export in the UI.
- Hide the QTI export option when the qti_converter plugin is disabled.
When it happens
Trigger: Running a content migration / course export with QTI format on a Canvas installation where the python qti_converter plugin is not enabled — python tool missing, plugin settings disabled, or a plain Canvas install without the converter dependency.
Common situations: Self-hosted Canvas missing the python QTI converter package; plugin disabled in /plugins/qti_converter; Docker/dev environment without the python dependency; export attempted before infrastructure provisioning.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Error running python qti converter: #
- bundler-multilock plugin is not installed
- Content Export for Outcomes Service failed
- Couldn't convert QTI 1.2 to 2.1, see error log: #
- Couldn't find QTI Migration Tool. See…
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/0603b7bf226b0c09.
Report an issue: GitHub.
Appendix: source
Thrown at gems/plugins/qti_exporter/lib/canvas/migration/worker/qti_worker.rb:31
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
module Canvas::Migration
module Worker
class QtiWorker < Base
def perform
cm = ContentMigration.where(id: migration_id).first
begin
cm.reset_job_progress
cm.job_progress.start
cm.update_conversion_progress(1)
plugin = Canvas::Plugin.find(:qti_converter)
unless plugin && plugin.settings[:enabled]
raise "Can't export QTI without the python converter tool installed."
end
settings = cm.migration_settings.clone
settings[:content_migration_id] = migration_id
settings[:user_id] = cm.user_id
settings[:content_migration] = cm
if cm.attachment
settings[:attachment_id] = cm.attachment.id
elsif settings[:file_url]
att = Canvas::Migration::Worker.download_attachment(cm, settings[:file_url])
settings[:attachment_id] = att.id
elsif !settings[:no_archive_file]
raise Canvas::Migration::Error, I18n.t(:no_migration_file, "File required for content migration.")
end
converter = Qti::Converter.new(settings)
assessments = converter.exportView on GitHub (pinned to 1c9f0bb801)