{"record":{"id":"f7e715378a3bdb20","repo":"Freika/dawarich","slug":"import-source-cannot-be-nil","errorCode":null,"errorMessage":"Import source cannot be nil","messagePattern":"Import source cannot be nil","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/services/imports/create.rb","lineNumber":97,"sourceCode":"        user:,\n        kind: :warning,\n        title: I18n.t('services.imports.create.import_post_processing_incomplete'),\n        content: I18n.t('services.imports.create.your_import_name_finished_and_all_points_were_saved_but',\n                        name: import.name, step: step.tr('_', ' '))\n      ).call\n    end\n  rescue StandardError => e\n    ExceptionReporter.call(e, 'Failed to create post-import failure notification')\n  end\n\n  def run_importer(path)\n    source = import.source.presence || detect_source_from_file(path)\n    import.update!(source: source) if import.source.to_s != source.to_s\n    importer(source).new(import, user.id, path).call\n  end\n\n  def importer(source)\n    raise ArgumentError, I18n.t('services.imports.create.source_missing') if source.nil?\n\n    case source.to_s\n    when 'google_semantic_history'      then GoogleMaps::SemanticHistoryImporter\n    when 'google_phone_takeout'         then GoogleMaps::PhoneTakeoutImporter\n    when 'google_records'               then GoogleMaps::RecordsStorageImporter\n    when 'google_photos'                then GooglePhotos::Importer\n    when 'owntracks'                    then OwnTracks::Importer\n    when 'gpx'                          then Gpx::TrackImporter\n    when 'kml'                          then Kml::Importer\n    when 'geojson'                      then Geojson::Importer\n    when 'immich_api', 'photoprism_api' then Photos::Importer\n    when 'csv'                          then Csv::Importer\n    when 'tcx'                          then Tcx::Importer\n    when 'fit'                          then Fit::Importer\n    when 'polarsteps'                   then Polarsteps::Importer\n    when 'zip'\n      raise ArgumentError, I18n.t('services.imports.create.zip_unclassified')\n    else","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/services/imports/create.rb#L79-L115","documentation":"Raised as ArgumentError by Imports::Create#importer when the import has no usable source: import.source is blank/whitespace AND detect_source_from_file (Imports::SourceDetector via new_from_file_header + detect_source!) returned nil — i.e. the file's magic bytes/header matched no known format. The dispatcher has no importer class to instantiate, so it fails before reading any points.","triggerScenarios":"Uploading a file format the detector does not recognize (e.g. an obscure tracker's binary export, a corrupted zip whose header is unreadable, an empty 0-byte file) without manually selecting a source; or a user choosing 'auto-detect' for a format outside the supported list (google takeout variants, owntracks, gpx, kml, geojson, immich/photoprism api, csv, tcx, fit, polarsteps).","commonSituations":"Renamed files (.gpx extension on JSON contents), uploads truncated so the header signature is missing, encrypted/password-protected zips whose inner header cannot be sniffed, brand-new formats users assume are supported.","solutions":["Re-upload and explicitly pick the source in the import form instead of relying on auto-detection.","Verify the file opens in its native app and has the expected extension-vs-content match (unzip -l for archives, head -c 200 for plain files).","If the format is genuinely unsupported, convert it to a supported one (GPX/GeoJSON/CSV) with gpsbabel or similar before importing.","For empty/corrupt uploads, check upload size limits and retry the transfer."],"exampleFix":"# before: auto-detect only\nimport.update!(source: nil)\nImports::Create.new(user, import).call # detect_source! -> nil -> ArgumentError\n\n# after: set the source explicitly on create\nimport.update!(source: 'gpx')\nImports::Create.new(user, import).call","handlingStrategy":"validation","validationCode":"source = import.source.presence || Imports::SourceDetector.new_from_file_header(path).detect_source!\nsource.present? || raise(ArgumentError, 'Unknown file type - select the import source manually')","typeGuard":"def known_import_source?(s) = %w[google_semantic_history google_phone_takeout google_records google_photos owntracks gpx kml geojson immich_api photoprism_api csv tcx fit polarsteps].include?(s.to_s)","tryCatchPattern":"begin\n  Imports::Create.new(user, import).call\nrescue ArgumentError => e\n  import.update!(status: :failed, error_message: 'Could not detect the file type. Choose the source manually and retry.')\nend","preventionTips":["Default the import form to an explicit source instead of auto-detect for unusual exporters.","Validate extension-vs-content on upload (magic bytes) and reject mismatches early.","Convert unsupported formats to GPX/GeoJSON/CSV before importing."],"tags":["import","file-type-detection","uploads","ruby"],"backgroundTag":"file-type-detection-failed","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}