{"record":{"id":"a4c38aaf374975ad","repo":"microg/GmsCore","slug":"unsupported-file-extension","errorCode":null,"errorMessage":"Unsupported file extension","messagePattern":"Unsupported file extension","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-location/core/provider/src/main/kotlin/org/microg/gms/location/network/LocationDatabase.kt","lineNumber":325,"sourceCode":"                        }\n                    })\n                    output.write(\",${midLocation.latitude},${midLocation.longitude},${if (midLocation.hasAltitude()) midLocation.altitude else \"\"}\\n\")\n                }\n            }\n            output.close()\n            return FileProvider.getUriForFile(context,\"${context.packageName}.microg.location.export\", exportFile)\n        } catch (e: Exception) {\n            Log.w(TAG, e)\n        }\n        return null\n    }\n\n    fun importLearned(fileUri: Uri): Int {\n        var counter = 0\n        try {\n            val type = context.contentResolver.getType(fileUri)\n            val gzip = if (type == null || type !in SUPPORTED_TYPES) {\n                if (fileUri.path == null) throw IllegalArgumentException(\"Unsupported file extension\")\n                if (fileUri.path!!.endsWith(\".gz\")) {\n                    true\n                } else if (fileUri.path!!.endsWith(\".csv\")) {\n                    false\n                } else {\n                    throw IllegalArgumentException(\"Unsupported file extension\")\n                }\n            } else {\n                type.endsWith(\"gzip\")\n            }\n            val desc = context.contentResolver.openFileDescriptor(fileUri, \"r\") ?: throw FileNotFoundException()\n            ParcelFileDescriptor.AutoCloseInputStream(desc).use { source ->\n                val input = (if (gzip) GZIPInputStream(source) else source).bufferedReader()\n                val headers = input.readLine().split(\",\")\n                val name = when {\n                    headers.containsAll(FIELDS_WIFI.toList()) && headers.containsAll(FIELDS_EXPORT_DATA.toList()) -> NAME_WIFI\n                    headers.containsAll(FIELDS_CELL.toList()) && headers.containsAll(FIELDS_EXPORT_DATA.toList()) -> NAME_CELL\n                    else -> null","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-location/core/provider/src/main/kotlin/org/microg/gms/location/network/LocationDatabase.kt#L307-L343","documentation":"LocationDatabase.importLearned throws IllegalArgumentException(\"Unsupported file extension\") when the content resolver cannot provide a MIME type (or it is not in SUPPORTED_TYPES) and the file URI's path is null or does not end with .gz or .csv. The import format cannot be determined.","triggerScenarios":"Calling importLearned(fileUri) with a URI whose contentResolver.getType() returns null or an unsupported type AND whose path (when non-null) lacks a .gz/.csv extension, or whose path is null entirely.","commonSituations":"Passing a content:// URI from a cloud/document provider where getType() returns null; sharing a file with a non-standard extension (e.g. .txt or no extension); DocumentFile URIs without a display name mapping.","solutions":["Import files whose MIME type is text/csv or application/gzip, or whose filename ends in .csv or .gz","Rename/copy the file so the URI exposes a .csv or .gz extension","If using ACTION_OPEN_DOCUMENT, pick files with recognizable csv/gz names","Catch IllegalArgumentException and prompt the user to select a supported export file"],"exampleFix":"// before\ndb.importLearned(anyUri)\n// after\nval type = contentResolver.getType(uri)\nval name = uri.lastPathSegment ?: \"\"\nrequire(type in SUPPORTED_TYPES || name.endsWith(\".csv\") || name.endsWith(\".gz\")) {\n    \"File must be a .csv or .gz export\"\n}\ndb.importLearned(uri)","handlingStrategy":"validation","validationCode":"val type = contentResolver.getType(uri)\nval path = uri.path ?: \"\"\nrequire(type in SUPPORTED_TYPES || path.endsWith(\".csv\") || path.endsWith(\".gz\")) {\n    \"File must be csv or gz\"\n}","typeGuard":"fun Uri.isSupportedLocationImport(resolver: ContentResolver): Boolean {\n    val type = resolver.getType(this)\n    val path = path ?: \"\"\n    return type in SUPPORTED_TYPES || path.endsWith(\".csv\") || path.endsWith(\".gz\")\n}","tryCatchPattern":"try {\n    db.importLearned(uri)\n} catch (e: IllegalArgumentException) {\n    if (e.message == \"Unsupported file extension\") showUnsupportedFileError() else throw e\n}","preventionTips":["Import only files exported as .csv or .csv.gz","Avoid providers that return null MIME types (e.g. some cloud URIs)","Use ACTION_OPEN_DOCUMENT to pick files with proper extensions","Validate the path/type before calling importLearned"],"tags":["android","csv","import","location"],"backgroundTag":"invalid-argument-value","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}