{"record":{"id":"54fac5e449100a13","repo":"MuntashirAkon/AppManager","slug":"no-splits-selected","errorCode":null,"errorMessage":"No splits selected.","messagePattern":"No splits selected\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerViewModel.java","lineNumber":261,"sourceCode":"                    UserHandleHidden.USER_ALL, false));\n        });\n    }\n\n    @Nullable\n    public PackageParseResult getCurrentPackage() {\n        return mCurrentPackage;\n    }\n\n    public Set<String> getSelectedSplits() {\n        return mSelectedSplits;\n    }\n\n    @NonNull\n    public ArrayList<String> getSelectedSplitsForInstallation() {\n        ApkFile apkFile = Objects.requireNonNull(mCurrentPackage).apkFile;\n        if (apkFile.isSplit()) {\n            if (mSelectedSplits.isEmpty()) {\n                throw new IllegalArgumentException(\"No splits selected.\");\n            }\n            return new ArrayList<>(mSelectedSplits);\n        }\n        return new ArrayList<>(Collections.singletonList(apkFile.getBaseEntry().id));\n    }\n\n    @WorkerThread\n    @NonNull\n    private PackageParseResult loadPackageInfo(@NonNull ApkQueueItem apkQueueItem) throws Throwable {\n        ApkSource apkSource;\n        ApkFile apkFile = null;\n        try {\n            PackageInfo installedPackageInfo = null;\n            if (apkQueueItem.isInstallExisting()) {\n                String packageName = apkQueueItem.getPackageName();\n                if (packageName == null) {\n                    throw new IllegalArgumentException(\"Package name not set for install-existing.\");\n                }","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/PackageInstallerViewModel.java#L243-L279","documentation":"PackageInstallerViewModel.getSelectedSplitsForInstallation() returns the user-selected splits for the package being installed. For a split APK (APK suite), the selection must contain at least one entry; if mSelectedSplits is empty an IllegalArgumentException is thrown because a split install cannot proceed with zero splits.","triggerScenarios":"Calling getSelectedSplitsForInstallation() after ApkFile.isSplit() is true but before the user (or caller) has selected any splits in mSelectedSplits — e.g. invoking install/start-install directly after loading a split APK without going through the split-selection screen.","commonSituations":"Automated flows that call the install method without the split-selection dialog; a UI bug that allows confirming with no checkboxes selected; ViewModel state reset (process death/config change) clearing mSelectedSplits before install is invoked.","solutions":["Ensure the split-selection step completes and populates mSelectedSplits (at minimum the base split) before calling getSelectedSplitsForInstallation()","Guard the call: only invoke it when apkFile.isSplit() is false or mSelectedSplits is non-empty","In the UI, disable the install button until at least one split is selected","Catch IllegalArgumentException and route the user back to the split-selection screen"],"exampleFix":"// before\nvm.startInstall(); // throws if no splits selected for a split APK\n// after\nif (!vm.getCurrentPackage().apkFile.isSplit() || vm.getSelectedSplits().isEmpty()) {\n    openSplitSelectionScreen();\n} else {\n    vm.startInstall();\n}","handlingStrategy":"validation","validationCode":"ApkFile apkFile = vm.getCurrentPackage().apkFile;\nif (apkFile.isSplit() && vm.getSelectedSplits().isEmpty()) {\n    // do not call getSelectedSplitsForInstallation(); open split picker instead\n}","typeGuard":"boolean canInstall(ApkFile apkFile, Set<String> selected) {\n    return !apkFile.isSplit() || !selected.isEmpty();\n}","tryCatchPattern":"try {\n    List<String> splits = vm.getSelectedSplitsForInstallation();\n} catch (IllegalArgumentException e) {\n    openSplitSelectionScreen();\n}","preventionTips":["Disable the install button until at least one split is selected","Restore mSelectedSplits after process death/config change","Only call getSelectedSplitsForInstallation after the split-selection step completed"],"tags":["android","apk-installer","split-apk","validation"],"backgroundTag":"empty-required-field","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}