instructure/canvas-lms · error

No migration file found

Error message

No migration file found

What it means

Canvas migration Archive expects a source file: either a downloaded archive from a provided URL, a local path, or an attachment id in settings. download_archive raises 'No migration file found' when none of these sources yield a file — i.e. @settings has no attachment_id, no archive/file, and no downloadable URL.

Solutions

  1. Include a valid source in migration settings: archive file bytes, a correct :attachment_id, or a downloadable archive URL
  2. Verify the attachment_id exists: Attachment.where(id: settings[:attachment_id]).exists?
  3. Check the migration job's settings serialization hasn't dropped the file keys
  4. Log settings keys before constructing Archive to spot the missing source

Example fix

// before
Canvas::Migration::Archive.new({migration_id: 5}) # no source
// after
Canvas::Migration::Archive.new({attachment_id: attachment.id})
Defensive patterns

Strategy: validation

Validate before calling

src = settings[:attachment_id] || settings[:archive] || settings[:archive_url]
raise 'migration archive source required' if src.blank?

Try / catch

begin
  archive.download_archive
rescue RuntimeError => e
  raise unless e.message == 'No migration file found'
  migration.workflow_state = :failed
  migration.add_warning(:missing_file, 'No source file provided')
end

Prevention

When it happens

Trigger: Creating Canvas::Migration::Archive with settings containing neither archive data, a resolvable URL, nor :attachment_id, then calling download_archive (or any content-import flow reaching it).

Common situations: API content migrations posted without the file/attachment_id parameter; the attachment was deleted between queueing and running the migration; caller passed the wrong settings keys.

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


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/9e5866cf03775791. Report an issue: GitHub.

Appendix: source

Thrown at lib/canvas/migration/archive.rb:106

      if @settings[:export_archive_path]
        File.open(@settings[:export_archive_path], "rb")
      elsif @settings[:course_archive_download_url].present?
        _, uri = CanvasHttp.validate_url(@settings[:course_archive_download_url], check_host: true)
        InstrumentTLSCiphers.without_tls_metrics do
          CanvasHttp.get(@settings[:course_archive_download_url]) do |http_response|
            raise CanvasHttp::InvalidResponseCodeError, http_response.code.to_i unless http_response.code.to_i == 200

            tmpfile = CanvasHttp.tempfile_for_uri(uri)
            http_response.read_body(tmpfile)
            tmpfile.rewind
            return tmpfile
          end
        end
      elsif @settings[:attachment_id]
        att = Attachment.find(@settings[:attachment_id])
        att.open(temp_folder: config[:data_folder])
      else
        raise "No migration file found"
      end
    end

    delegate :path, to: :file

    def unzipped_file_path
      unless @unzipped_file_path
        config = ConfigFile.load("external_migration") || {}
        @unzipped_file_path = Dir.mktmpdir(nil, config[:data_folder].presence)
      end
      @unzipped_file_path
    end

    def package_root
      @package_root ||= PackageRoot.new(unzipped_file_path)
    end

    def get_converter

View on GitHub (pinned to 1c9f0bb801)