{"record":{"id":"0b86bd89db4feb21","repo":"microg/GmsCore","slug":"app-unavailable","errorCode":"APP_UNAVAILABLE","errorMessage":"e.message","messagePattern":"e\\.message","errorType":"error_code","errorClass":"AssetPackException","httpStatus":null,"severity":"error","filePath":"vending-app/src/main/kotlin/com/google/android/finsky/extensions.kt","lineNumber":52,"sourceCode":"import org.microg.vending.billing.GServices\nimport org.microg.vending.billing.core.GooglePlayApi\nimport org.microg.vending.billing.core.HttpClient\nimport java.io.File\nimport java.util.Collections\n\nconst val KEY_MODULE_NAME = \"module_name\"\n\nconst val TAG_REQUEST = \"asset_module\"\n\nprivate const val ASSET_MODULE_DELIVERY_URL = \"https://play-fe.googleapis.com/fdfe/assetModuleDelivery\"\n\nprivate const val TAG = \"AssetModuleRequest\"\n\nfun getAppVersionCode(context: Context, packageName: String): Long? {\n    return try {\n        PackageInfoCompat.getLongVersionCode(context.packageManager.getPackageInfo(packageName, 0))\n    } catch (e: PackageManager.NameNotFoundException) {\n        throw AssetPackException(AssetPackErrorCode.APP_UNAVAILABLE, e.message)\n    }\n}\n\nfun <T> Bundle?.get(key: BundleKeys.RootKey<T>): T? = if (this == null) null else BundleKeys.get(this, key)\nfun <T> Bundle?.get(key: BundleKeys.RootKey<T>, def: T): T = if (this == null) def else BundleKeys.get(this, key, def)\nfun <T> Bundle.put(key: BundleKeys.RootKey<T>, v: T) = BundleKeys.put(this, key, v)\nfun <T> Bundle.put(key: BundleKeys.PackKey<T>, packName: String, v: T) = BundleKeys.put(this, key, packName, v)\nfun <T> Bundle.put(key: BundleKeys.SliceKey<T>, packName: String, sliceId: String, v: T) = BundleKeys.put(this, key, packName, sliceId, v)\nfun <T> bundleOf(pair: Pair<BundleKeys.RootKey<T>, T>): Bundle = Bundle().apply { put(pair.first, pair.second) }\noperator fun Bundle.plus(other: Bundle): Bundle = Bundle(this).apply { putAll(other) }\noperator fun <T> Bundle.plus(pair: Pair<BundleKeys.RootKey<T>, T>): Bundle = this + bundleOf(pair)\n\nval Context.assetPacksDir: File\n    get() = File(filesDir, \"assetpacks\")\nfun Context.getSessionDir(sessionId: Int) =\n    File(assetPacksDir, sessionId.toString())\nfun Context.getModuleDir(sessionId: Int, moduleName: String): File =\n    File(getSessionDir(sessionId), moduleName)","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/vending-app/src/main/kotlin/com/google/android/finsky/extensions.kt#L34-L70","documentation":"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.","triggerScenarios":"Calling getAppVersionCode for a packageName that has no PackageInfo — i.e., getPackageInfo throws PackageManager.NameNotFoundException.","commonSituations":"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.","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"],"exampleFix":"// before\nval versionCode = getAppVersionCode(context, packageName)!!\n// after\ntry {\n    val versionCode = getAppVersionCode(context, packageName)\n} catch (e: AssetPackException) {\n    if (e.errorCode == AssetPackErrorCode.APP_UNAVAILABLE) {\n        // trigger install / show unavailable state\n    }\n}","handlingStrategy":"try-catch","validationCode":"fun isPackageInstalled(pm: PackageManager, name: String) =\n    try { pm.getPackageInfo(name, 0); true } catch (e: PackageManager.NameNotFoundException) { false }","typeGuard":null,"tryCatchPattern":"try {\n    val code = getAppVersionCode(context, packageName)\n} catch (e: AssetPackException) {\n    if (e.errorCode == AssetPackErrorCode.APP_UNAVAILABLE) {\n        // route user to Play Store install\n    }\n}","preventionTips":["Check installation state before reading package metadata","Validate package name spelling/constant","Handle uninstall races by re-checking before dependent operations"],"tags":["kotlin","android","packagemanager","asset-pack","package-not-found"],"backgroundTag":"resource-not-found","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"}