microg/GmsCore · error · IllegalArgumentException

Unsupported file extension

Error message

Unsupported file extension

What it means

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.

Source

Thrown at play-services-location/core/provider/src/main/kotlin/org/microg/gms/location/network/LocationDatabase.kt:325

                        }
                    })
                    output.write(",${midLocation.latitude},${midLocation.longitude},${if (midLocation.hasAltitude()) midLocation.altitude else ""}\n")
                }
            }
            output.close()
            return FileProvider.getUriForFile(context,"${context.packageName}.microg.location.export", exportFile)
        } catch (e: Exception) {
            Log.w(TAG, e)
        }
        return null
    }

    fun importLearned(fileUri: Uri): Int {
        var counter = 0
        try {
            val type = context.contentResolver.getType(fileUri)
            val gzip = if (type == null || type !in SUPPORTED_TYPES) {
                if (fileUri.path == null) throw IllegalArgumentException("Unsupported file extension")
                if (fileUri.path!!.endsWith(".gz")) {
                    true
                } else if (fileUri.path!!.endsWith(".csv")) {
                    false
                } else {
                    throw IllegalArgumentException("Unsupported file extension")
                }
            } else {
                type.endsWith("gzip")
            }
            val desc = context.contentResolver.openFileDescriptor(fileUri, "r") ?: throw FileNotFoundException()
            ParcelFileDescriptor.AutoCloseInputStream(desc).use { source ->
                val input = (if (gzip) GZIPInputStream(source) else source).bufferedReader()
                val headers = input.readLine().split(",")
                val name = when {
                    headers.containsAll(FIELDS_WIFI.toList()) && headers.containsAll(FIELDS_EXPORT_DATA.toList()) -> NAME_WIFI
                    headers.containsAll(FIELDS_CELL.toList()) && headers.containsAll(FIELDS_EXPORT_DATA.toList()) -> NAME_CELL
                    else -> null

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Import files whose MIME type is text/csv or application/gzip, or whose filename ends in .csv or .gz
  2. Rename/copy the file so the URI exposes a .csv or .gz extension
  3. If using ACTION_OPEN_DOCUMENT, pick files with recognizable csv/gz names
  4. Catch IllegalArgumentException and prompt the user to select a supported export file

Example fix

// before
db.importLearned(anyUri)
// after
val type = contentResolver.getType(uri)
val name = uri.lastPathSegment ?: ""
require(type in SUPPORTED_TYPES || name.endsWith(".csv") || name.endsWith(".gz")) {
    "File must be a .csv or .gz export"
}
db.importLearned(uri)
Defensive patterns

Strategy: validation

Validate before calling

val type = contentResolver.getType(uri)
val path = uri.path ?: ""
require(type in SUPPORTED_TYPES || path.endsWith(".csv") || path.endsWith(".gz")) {
    "File must be csv or gz"
}

Type guard

fun Uri.isSupportedLocationImport(resolver: ContentResolver): Boolean {
    val type = resolver.getType(this)
    val path = path ?: ""
    return type in SUPPORTED_TYPES || path.endsWith(".csv") || path.endsWith(".gz")
}

Try / catch

try {
    db.importLearned(uri)
} catch (e: IllegalArgumentException) {
    if (e.message == "Unsupported file extension") showUnsupportedFileError() else throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/a4c38aaf374975ad. Report an issue: GitHub.