microg/GmsCore · error · AssetPackException
APP_UNAVAILABLE
APP_UNAVAILABLE
Error message
e.message
What it means
getAppVersionCode wraps PackageManager.NameNotFoundException into AssetPackException(APP_UNAVAILABLE, e.message). The message surfaced ('e.message') is the underlying NameNotFoundException text, typically the package name that could not be resolved. It means the queried package is not installed on the device.
Source
Thrown at vending-app/src/main/kotlin/com/google/android/finsky/extensions.kt:52
import org.microg.vending.billing.GServices
import org.microg.vending.billing.core.GooglePlayApi
import org.microg.vending.billing.core.HttpClient
import java.io.File
import java.util.Collections
const val KEY_MODULE_NAME = "module_name"
const val TAG_REQUEST = "asset_module"
private const val ASSET_MODULE_DELIVERY_URL = "https://play-fe.googleapis.com/fdfe/assetModuleDelivery"
private const val TAG = "AssetModuleRequest"
fun getAppVersionCode(context: Context, packageName: String): Long? {
return try {
PackageInfoCompat.getLongVersionCode(context.packageManager.getPackageInfo(packageName, 0))
} catch (e: PackageManager.NameNotFoundException) {
throw AssetPackException(AssetPackErrorCode.APP_UNAVAILABLE, e.message)
}
}
fun <T> Bundle?.get(key: BundleKeys.RootKey<T>): T? = if (this == null) null else BundleKeys.get(this, key)
fun <T> Bundle?.get(key: BundleKeys.RootKey<T>, def: T): T = if (this == null) def else BundleKeys.get(this, key, def)
fun <T> Bundle.put(key: BundleKeys.RootKey<T>, v: T) = BundleKeys.put(this, key, v)
fun <T> Bundle.put(key: BundleKeys.PackKey<T>, packName: String, v: T) = BundleKeys.put(this, key, packName, v)
fun <T> Bundle.put(key: BundleKeys.SliceKey<T>, packName: String, sliceId: String, v: T) = BundleKeys.put(this, key, packName, sliceId, v)
fun <T> bundleOf(pair: Pair<BundleKeys.RootKey<T>, T>): Bundle = Bundle().apply { put(pair.first, pair.second) }
operator fun Bundle.plus(other: Bundle): Bundle = Bundle(this).apply { putAll(other) }
operator fun <T> Bundle.plus(pair: Pair<BundleKeys.RootKey<T>, T>): Bundle = this + bundleOf(pair)
val Context.assetPacksDir: File
get() = File(filesDir, "assetpacks")
fun Context.getSessionDir(sessionId: Int) =
File(assetPacksDir, sessionId.toString())
fun Context.getModuleDir(sessionId: Int, moduleName: String): File =
File(getSessionDir(sessionId), moduleName)View on GitHub (pinned to 157c9d86ac)
Solutions
- Verify the package name spelling and that the app is installed before querying its version code
- Catch AssetPackException with APP_UNAVAILABLE and prompt install via Play
- Re-check installation state at the moment of the call (handle races)
- For asset packs, ensure the base app is installed and Play Core is current
Example fix
// before
val versionCode = getAppVersionCode(context, packageName)!!
// after
try {
val versionCode = getAppVersionCode(context, packageName)
} catch (e: AssetPackException) {
if (e.errorCode == AssetPackErrorCode.APP_UNAVAILABLE) {
// trigger install / show unavailable state
}
} Defensive patterns
Strategy: try-catch
Validate before calling
fun isPackageInstalled(pm: PackageManager, name: String) =
try { pm.getPackageInfo(name, 0); true } catch (e: PackageManager.NameNotFoundException) { false } Try / catch
try {
val code = getAppVersionCode(context, packageName)
} catch (e: AssetPackException) {
if (e.errorCode == AssetPackErrorCode.APP_UNAVAILABLE) {
// route user to Play Store install
}
} Prevention
- Check installation state before reading package metadata
- Validate package name spelling/constant
- Handle uninstall races by re-checking before dependent operations
When it happens
Trigger: Calling getAppVersionCode for a packageName that has no PackageInfo — i.e., getPackageInfo throws PackageManager.NameNotFoundException.
Common situations: Play Asset Pack requested for an app that is not installed; typo in package name; instant/asset module delivered before the base app installs; uninstall between check and query.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Missing package name
- IntegrityErrorCode.NONCE_TOO_SHORT
- IntegrityErrorCode.NONCE_TOO_LONG
- deleteAll was set to true but keys were also provided
- Element in keys cannot be null or empty
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/0b86bd89db4feb21.
Report an issue: GitHub.