Freika/dawarich · error · ArgumentError

Could not classify zip contents -- file may be corrupted

Error message

Could not classify zip contents -- file may be corrupted

What it means

ArgumentError raised by Imports::Create#importer when the resolved import source is the literal string 'zip'. A .zip upload is supposed to be unpacked and re-dispatched by Archive::Unzipper.inspect_archive (:multi_entry goes to ZipExtractor, :single_entry extracts the inner file and re-detects); reaching importer('zip') means the archive's contents fit neither shape, so no concrete importer exists to run and the service refuses with 'Could not classify zip contents -- file may be corrupted'.

Source

Thrown at app/services/imports/create.rb:114

  def importer(source)
    raise ArgumentError, I18n.t('services.imports.create.source_missing') if source.nil?

    case source.to_s
    when 'google_semantic_history'      then GoogleMaps::SemanticHistoryImporter
    when 'google_phone_takeout'         then GoogleMaps::PhoneTakeoutImporter
    when 'google_records'               then GoogleMaps::RecordsStorageImporter
    when 'google_photos'                then GooglePhotos::Importer
    when 'owntracks'                    then OwnTracks::Importer
    when 'gpx'                          then Gpx::TrackImporter
    when 'kml'                          then Kml::Importer
    when 'geojson'                      then Geojson::Importer
    when 'immich_api', 'photoprism_api' then Photos::Importer
    when 'csv'                          then Csv::Importer
    when 'tcx'                          then Tcx::Importer
    when 'fit'                          then Fit::Importer
    when 'polarsteps'                   then Polarsteps::Importer
    when 'zip'
      raise ArgumentError, I18n.t('services.imports.create.zip_unclassified')
    else
      raise ArgumentError, I18n.t('services.imports.create.unsupported_source', source:)
    end
  end

  def update_import_points_count(import)
    Import::UpdatePointsCountJob.perform_later(import.id)
  end

  def notify_if_all_skipped(import)
    import.reload
    return unless import.points.count.zero?

    if import.doubles.to_i.positive?
      I18n.with_locale(import.user.locale) do
        Notification.create!(
          user_id: import.user_id,
          title: I18n.t('services.imports.create.import_completed_with_no_new_points'),

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Verify the zip opens locally (unzip -t) and re-download/re-create it if damaged
  2. Extract the zip manually and upload the meaningful inner file directly (Records.json, timeline.json, .gpx, .tcx, etc.)
  3. For multi-file Takeout zips, make sure recognizable entries (Records.json / timeline JSONs) are actually inside
  4. Check server logs for the Archive::Unzipper.inspect_archive result to see why neither dispatch kind matched

Example fix

# before: uploading an arbitrary .zip and expecting Dawarich to figure it out
Import.create!(source: 'zip', file: my_mystery_zip)

# after: extract and upload the inner location file directly
# unzip takeout.zip -d takeout && upload takeout/Takeout/Location History/Records.json
Import.create!(file: File.open('takeout/Records.json'))  # source auto-detected
Defensive patterns

Strategy: validation

Validate before calling

# Classify the archive BEFORE creating/processing the import
kind = Archive::Unzipper.inspect_archive(zip_path).kind
unless %i[multi_entry single_entry].include?(kind)
  raise ArgumentError, "Zip contents unclassifiable (kind=#{kind.inspect}); extract it and upload the inner file directly"
end

Type guard

def classifiable_zip?(path)
  return false unless File.extname(path).downcase == '.zip'
  %i[multi_entry single_entry].include?(Archive::Unzipper.inspect_archive(path).kind)
end

Try / catch

begin
  Imports::Create.new(user, import).call
rescue ArgumentError => e
  import.update!(status: :failed, error_message: e.message) # Imports::Create already does this; hook here for custom UX
end

Prevention

When it happens

Trigger: Uploading a file with a .zip extension and valid PK\x03\x04 magic bytes whose entries are all unrecognized by the unzipper's classification (no importable inner files), a zip whose central directory is damaged so inspect_archive returns neither :multi_entry nor :single_entry, or an effectively empty zip that still passes zip_file?.

Common situations: Partially downloaded or interrupted Google Takeout zips, archives re-packed by tools that wrap files in an unexpected layout, re-uploading an already-extracted export, or an Import record whose source column was manually set to 'zip'.

Related errors


AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21). Data as JSON: /api/errors/740bc56a24735a0a. Report an issue: GitHub.