{"record":{"id":"d0234703501774b0","repo":"asLody/VirtualApp","slug":"must-specify-package-name-to-remove-a-split","errorCode":null,"errorMessage":"Must specify package name to remove a split","messagePattern":"Must specify package name to remove a split","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/PackageInstallerSession.java","lineNumber":353,"sourceCode":"\n        try {\n            if (!FileUtils.isValidExtFilename(name)) {\n                throw new IllegalArgumentException(\"Invalid name: \" + name);\n            }\n            final File target = new File(resolveStageDir(), name);\n\n            final FileDescriptor targetFd = Os.open(target.getAbsolutePath(), O_RDONLY, 0);\n            return ParcelFileDescriptor.dup(targetFd);\n\n        } catch (ErrnoException e) {\n            throw new IOException(e);\n        }\n    }\n\n    @Override\n    public void removeSplit(String splitName) throws RemoteException {\n        if (TextUtils.isEmpty(params.appPackageName)) {\n            throw new IllegalStateException(\"Must specify package name to remove a split\");\n        }\n        try {\n            createRemoveSplitMarker(splitName);\n        } catch (IOException e) {\n            throw new IllegalStateException(e);\n        }\n    }\n\n    private void createRemoveSplitMarker(String splitName) throws IOException {\n        try {\n            final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION;\n            if (!FileUtils.isValidExtFilename(markerName)) {\n                throw new IllegalArgumentException(\"Invalid marker: \" + markerName);\n            }\n            final File target = new File(resolveStageDir(), markerName);\n            target.createNewFile();\n            Os.chmod(target.getAbsolutePath(), 0 /*mode*/);\n        } catch (ErrnoException e) {","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/asLody/VirtualApp/blob/666fefcb5d3f39cc944001c3457c38ffd6544c87/VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/PackageInstallerSession.java#L335-L371","documentation":"removeSplit() only makes sense for split-APK installs, which must be targeted at an explicit package name. If params.appPackageName is empty/null, the session has no package against which to mark a split for removal, so it throws IllegalStateException('Must specify package name to remove a split').","triggerScenarios":"Calling session.removeSplit(splitName) on a session whose SessionParams.appPackageName was never set (e.g. install-mode params built without setting the package name).","commonSituations":"Installing via stream/data URL without an app package name; reusing generic SessionParams for a full APK install and then attempting split maintenance; VirtualApp flows where the base package was installed by other means.","solutions":["Set params.appPackageName (SessionParams.setAppPackageName) before creating the session.","Only call removeSplit for sessions performing split-APK installs.","If the package is unknown, skip removeSplit and instead install a fresh full APK replacing the old one."],"exampleFix":"// before\nSessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);\nsession.removeSplit(\"split_config.arm64_v8a\"); // IllegalStateException\n\n// after\nSessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);\nparams.setAppPackageName(\"com.example.app\");\n// ... create/open session ...\nsession.removeSplit(\"split_config.arm64_v8a\");","handlingStrategy":"validation","validationCode":"if (params == null || TextUtils.isEmpty(params.appPackageName)) {\n    throw new IllegalArgumentException(\"appPackageName must be set before removeSplit\");\n}","typeGuard":"boolean canRemoveSplits(SessionParams p) { return p != null && !TextUtils.isEmpty(p.appPackageName); }","tryCatchPattern":"try {\n    session.removeSplit(splitName);\n} catch (IllegalStateException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Must specify package name\")) {\n        // re-create session with setAppPackageName, or skip split removal\n    } else throw e;\n}","preventionTips":["Always call params.setAppPackageName(...) when building SessionParams.","Only use removeSplit in split-APK install flows.","Assert appPackageName non-empty in session setup code."],"tags":["illegal-state","missing-package-name","split-apk","android"],"backgroundTag":"missing-required-argument","analyzedSha":"666fefcb5d3f39cc944001c3457c38ffd6544c87","analyzedAt":"2026-09-09T11:09:01.694Z","contentChangedAt":"2026-09-09T11:09:01.694Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}