MuntashirAkon/AppManager · error · JSONException
Selected APK splits are missing.
Error message
Selected APK splits are missing.
What it means
ApkQueueItem.validateForReplay() requires mSelectedSplits (the chosen split APKs of a split/APK-suite install) to be non-null and non-empty when mInstallExisting is false. A split APK cannot be installed without knowing which splits to include, so a JSONException is thrown.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/apk/installer/ApkQueueItem.java:238
mOriginatingUri = originatingUri != null ? Uri.parse(originatingUri) : null;
JSONObject apkSource = jsonObject.optJSONObject("apk_source");
mApkSource = apkSource != null ? ApkSource.DESERIALIZER.deserialize(apkSource) : null;
JSONObject installerOptions = jsonObject.optJSONObject("installer_options");
mInstallerOptions = installerOptions != null ? InstallerOptions.DESERIALIZER.deserialize(installerOptions) : null;
mSelectedSplits = JSONUtils.getArray(jsonObject.optJSONArray("selected_splits"));
}
public void validateForReplay() throws JSONException {
if (mInstallExisting) {
if (TextUtils.isEmpty(mPackageName)) {
throw new JSONException("Package name is missing.");
}
} else {
if (mApkSource == null) {
throw new JSONException("APK source is missing.");
}
if (mSelectedSplits == null || mSelectedSplits.isEmpty()) {
throw new JSONException("Selected APK splits are missing.");
}
}
if (mInstallerOptions != null) {
setInstallerOptions(InstallerOptions.resolveEffectiveOptions(mInstallerOptions,
mPackageName, mTestOnly));
}
}
@NonNull
@Override
public JSONObject serializeToJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("op_id", mOperationId);
jsonObject.put("package_name", mPackageName);
jsonObject.put("app_label", mAppLabel);
jsonObject.put("install_existing", mInstallExisting);
jsonObject.put("test_only", mTestOnly);
jsonObject.put("originating_package", mOriginatingPackage);View on GitHub (pinned to 0152f468fc)
Solutions
- Persist/populate mSelectedSplits (selected_splits in JSON) with at least the base split before replay
- For non-split packages, include the base entry id as the single selected split
- Validate split selection in the UI (require at least the base split) before creating the queue item
- Catch JSONException around getExecutableIntent and re-prompt the user to choose splits
Example fix
// before
JSONObject obj = new JSONObject(json); // selected_splits absent
ApkQueueItem item = new ApkQueueItem(obj);
item.getExecutableIntent(context); // throws
// after
if (obj.optJSONArray("selected_splits") == null) {
JSONArray splits = new JSONArray();
splits.put("base");
obj.put("selected_splits", splits);
}
ApkQueueItem item = new ApkQueueItem(obj);
item.getExecutableIntent(context); Defensive patterns
Strategy: validation
Validate before calling
if (!item.isInstallExisting() && (item.getSelectedSplits() == null || item.getSelectedSplits().isEmpty())) {
throw new IllegalStateException("Select at least the base split before installing.");
} Type guard
boolean hasSplits(ApkQueueItem item) {
return item.isInstallExisting()
|| (item.getSelectedSplits() != null && !item.getSelectedSplits().isEmpty());
} Try / catch
try {
Intent i = item.getExecutableIntent(context);
} catch (JSONException e) {
if (e.getMessage().contains("splits")) {
openSplitSelectionScreen();
}
} Prevention
- Require at least the base split to be selected in the UI before queuing
- Persist selected_splits in session JSON
- For non-split packages, default selected splits to the base entry id
When it happens
Trigger: Replaying a queue item whose apkFile is a split APK suite but mSelectedSplits is null or empty — e.g. the selected_splits array was never saved in the JSON, or the user deselected all splits before queuing.
Common situations: Deserializing a saved install session missing the selected_splits key; programmatically building an ApkQueueItem for a split APK without calling the split-selection API; a UI flow that allowed confirming an install with zero splits checked.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- APK source is missing.
- No splits selected.
- Package name not set for install-existing.
- Invalid queue item.
- "manifest" has duplicate "application" tags.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/1ae7c53013964e5c.
Report an issue: GitHub.