Freika/dawarich · error · Users::ImportData::UnsupportedFormatError

Unknown export format: neither manifest.json nor data.json f

Error message

Unknown export format: neither manifest.json nor data.json found

What it means

Users::ImportData::UnsupportedFormatError raised by detect_format_version when the extracted archive contains neither manifest.json (the v2 marker) nor data.json (the v1 marker) at its root. The service can only restore archives produced by Dawarich's own Users::ExportData - format detection is purely 'which marker file exists' - so anything with an unrecognized layout is refused with 'Unknown export format'.

Source

Thrown at app/services/users/import_data.rb:197

    ExceptionReporter.call(e, 'Anomaly filtering failed after data import')
  end

  def detect_format_version
    manifest_path = @import_directory.join('manifest.json')
    data_json_path = @import_directory.join('data.json')

    if File.exist?(manifest_path)
      begin
        manifest = JSON.parse(File.read(manifest_path))
        manifest['format_version'] || 2
      rescue JSON::ParserError
        Rails.logger.warn 'Failed to parse manifest.json, falling back to v2'
        2
      end
    elsif File.exist?(data_json_path)
      1 # Legacy format
    else
      raise UnsupportedFormatError, I18n.t('services.users.import_data.unknown_export_format')
    end
  end

  def create_handler(format_version)
    case format_version
    when 1
      Users::ImportData::V1Handler.new(user, @import_directory, @import_stats)
    when 2
      Users::ImportData::V2Handler.new(user, @import_directory, @import_stats)
    else
      raise StandardError, I18n.t('services.users.import_data.unsupported_format_version', version: format_version)
    end
  end

  def cleanup_temporary_files(import_directory)
    return unless File.directory?(import_directory)

    Rails.logger.info "Cleaning up temporary import directory: #{import_directory}"

View on GitHub (pinned to 97fad417c5)

Solutions

  1. List the archive contents (unzip -l) and confirm manifest.json (or legacy data.json) is at the root, not nested
  2. Re-zip so the marker file is a root entry: cd into the folder containing manifest.json before zipping
  3. If the archive is raw location data rather than a Dawarich export, use the regular Imports flow instead
  4. Re-export from the source Dawarich instance to get a pristine archive

Example fix

# before: nested layout after a drag-and-drop re-pack
# export.zip/backup-v2/manifest.json  <- marker not at root

# after: re-zip from inside the folder
cd backup-v2 && zip -r ../export-fixed.zip .   # manifest.json now at root
Defensive patterns

Strategy: validation

Validate before calling

entry_names = Zip::File.open(archive_path) { |z| z.entries.reject(&:directory?).map(&:name) }
unless entry_names.include?('manifest.json') || entry_names.include?('data.json')
  raise Users::ImportData::UnsupportedFormatError, 'not a Dawarich export (no manifest.json/data.json at root)'
end

Type guard

def dawarich_export?(archive_path)
  names = Zip::File.open(archive_path) { |z| z.entries.map(&:name) }
  names.include?('manifest.json') || names.include?('data.json')
end

Try / catch

begin
  Users::ImportData.new(user, archive).import
rescue Users::ImportData::UnsupportedFormatError => e
  # service already creates a failure notification and returns nil; add UI guidance here
  render json: { error: e.message }, status: :unprocessable_entity
end

Prevention

When it happens

Trigger: Feeding the user-data import a zip that is not a Dawarich export at all (e.g. a Google Takeout zip), an export re-packed so the marker sits inside a subdirectory, or a zip whose root-level marker entry was skipped during extraction by sanitize_zip_entry_name (path traversal) or the MAX_ENTRY_SIZE check.

Common situations: Confusing the point-import feature with the full user-data restore feature, re-zipping an export with an extra top-level folder ('export-v2/manifest.json'), or hand-modifying an export archive.

Related errors


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