instructure/canvas-lms · error · Canvas::Migration::Error
no_migration_file
no_migration_file
Error message
File required for content migration.
What it means
ZipFileWorker#perform requires an archive source: the content migration's attachment, or a file_url to download. If neither exists (and settings do not disable the archive-file requirement), Canvas::Migration::Error with 'File required for content migration.' is raised (I18n key :no_migration_file).
Solutions
- Attach a file to the content migration (cm.attachment = ...) or set cm.migration_settings[:file_url] before queueing the job
- Re-run the import through the UI so the upload completes before the worker processes
- Verify the attachment wasn't deleted/failed upload (check file_state) between enqueue and perform
- For API-driven migrations, include file_url in migration_settings when not uploading directly
Example fix
// before (API body)
{ "migration_type": "zip_file_importer", "settings": { "folder_id": 12 } }
// after
{ "migration_type": "zip_file_importer", "settings": { "folder_id": 12, "file_url": "https://files.example.com/pkg.zip" } } Defensive patterns
Strategy: validation
Validate before calling
raise 'no source file' if cm.attachment.nil? && cm.migration_settings[:file_url].blank?
Type guard
has_source = !cm.attachment.nil? || cm.migration_settings[:file_url].present?
Try / catch
begin
cm.run
rescue Canvas::Migration::Error => e
if e.message.include?('File required')
redirect_to upload_step_path(cm)
end
end Prevention
- Require file upload in the UI before allowing import submission
- Guard API endpoints to accept attachment or file_url
- Check attachment file_state is not 'errored'/'deleted' before queueing
When it happens
Trigger: Performing a zip_file_importer / unzip migration when cm.attachment is nil and cm.migration_settings[:file_url] is not set.
Common situations: Creating a ContentMigration via API without attaching a file or passing file_url, attachment deleted before the job ran, migration settings lost between queueing and processing.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- File not found
- File required for content migration.
- att.upload_error_message
- # : #
- Destination '# ' already exists
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/840401384803b08d.
Report an issue: GitHub.
Appendix: source
Thrown at lib/canvas/migration/worker/zip_file_worker.rb:37
#
class Canvas::Migration::Worker::ZipFileWorker < Canvas::Migration::Worker::Base
def perform(cm = nil)
cm ||= ContentMigration.find migration_id
cm.save if cm.capture_job_id
cm.workflow_state = :importing
cm.migration_settings[:skip_import_notification] = true
cm.job_progress.start
cm.save
begin
if cm.attachment
zipfile = cm.attachment.open
elsif cm.migration_settings[:file_url]
att = Canvas::Migration::Worker.download_attachment(cm, cm.migration_settings[:file_url])
zipfile = att.open
elsif !settings[:no_archive_file]
raise Canvas::Migration::Error, I18n.t(:no_migration_file, "File required for content migration.")
end
folder = cm.context.folders.find(cm.migration_settings[:folder_id])
update_callback = lambda do |pct|
percent_complete = pct * 100
scaled = percent_complete
if cm.import_immediately?
scaled = (scaled / 2) + 50
end
# Only update if progress has incremented 1 percent
if scaled - cm.progress >= 1
cm.update_import_progress(percent_complete)
end
endView on GitHub (pinned to 1c9f0bb801)