instructure/canvas-lms · error · CanvasUnzip::CanvasUnzipError

Invalid entry type

Error message

Invalid entry type

What it means

CanvasUnzip::Entry#initialize wraps either a Zip::Entry or a Gem::Package::TarReader::Entry and raises CanvasUnzipError "Invalid entry type" if the object passed is neither — it cannot determine the archive type (@type stays nil). This is an internal invariant; it surfaces when Entry is constructed with an unsupported/foreign object.

Solutions

  1. Obtain entries via CanvasUnzip.each_entry / extract_archive instead of constructing Entry yourself.
  2. Check which class the object actually is (obj.class) and whether the installed rubyzip/gem versions match what CanvasUnzip expects (update Gemfile).
  3. If you must construct Entry, pass a genuine Zip::Entry or Gem::Package::TarReader::Entry.
  4. Rescue CanvasUnzip::CanvasUnzipError in custom pipelines and log the offending entry class.

Example fix

// before
entry = CanvasUnzip::Entry.new(OpenStruct.new(name: "a.txt")) # raises
// after
CanvasUnzip.each_entry(path) { |entry, _i| process(entry) } # entries built internally
Defensive patterns

Strategy: try-catch

Validate before calling

raise TypeError, "unsupported entry class #{obj.class}" unless obj.is_a?(Zip::Entry) || obj.is_a?(Gem::Package::TarReader::Entry)

Type guard

def valid_entry?(obj)
  obj.is_a?(Zip::Entry) || obj.is_a?(Gem::Package::TarReader::Entry)
end

Try / catch

begin
  entry = CanvasUnzip::Entry.new(obj)
rescue CanvasUnzip::CanvasUnzipError
  Rails.logger.warn("cannot wrap entry of class #{obj.class}")
  nil
end

Prevention

When it happens

Trigger: Calling CanvasUnzip::Entry.new(some_other_object) directly; library-internal changes where a new entry class (e.g. from a different zip gem version) isn't in the case statement; monkey-patching or stubbing entries in tests with doubles.

Common situations: Custom extraction code bypassing each_entry and building Entry objects manually; gem version upgrades changing Zip::Entry's class/namespace; test fakes passed where a real entry is expected.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at gems/canvas_unzip/lib/canvas_unzip.rb:172

  def self.compute_uncompressed_size(archive_filename)
    total_size = 0
    each_entry(archive_filename) { |entry, _index| total_size += entry.size }
    total_size
  end

  class Entry
    attr_reader :entry, :type

    def initialize(entry)
      case entry
      when Zip::Entry
        @type = :zip
      when Gem::Package::TarReader::Entry
        @type = :tar
      end

      raise CanvasUnzipError, "Invalid entry type" unless @type

      @entry = entry
    end

    def symlink?
      case type
      when :zip
        entry.symlink?
      when :tar
        entry.header.typeflag == "2"
      end
    end

    delegate :directory?, :file?, to: :entry

    def name
      @name ||= case type
                when :zip

View on GitHub (pinned to 1c9f0bb801)