{"record":{"id":"8ca828010d773aa0","repo":"asLody/VirtualApp","slug":"failed-to-allocate-session-id","errorCode":null,"errorMessage":"Failed to allocate session ID","messagePattern":"Failed to allocate session ID","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/VPackageInstallerService.java","lineNumber":270,"sourceCode":"            }\n        }\n    }\n\n    private boolean isCallingUidOwner(PackageInstallerSession session) {\n        return true;\n    }\n\n    private int allocateSessionIdLocked() {\n        int n = 0;\n        int sessionId;\n        do {\n            sessionId = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;\n            if (mSessions.get(sessionId) == null) {\n                return sessionId;\n            }\n        } while (n++ < 32);\n\n        throw new IllegalStateException(\"Failed to allocate session ID\");\n    }\n\n    private static class Callbacks extends Handler {\n        private static final int MSG_SESSION_CREATED = 1;\n        private static final int MSG_SESSION_BADGING_CHANGED = 2;\n        private static final int MSG_SESSION_ACTIVE_CHANGED = 3;\n        private static final int MSG_SESSION_PROGRESS_CHANGED = 4;\n        private static final int MSG_SESSION_FINISHED = 5;\n\n        private final RemoteCallbackList<IPackageInstallerCallback>\n                mCallbacks = new RemoteCallbackList<>();\n\n        public Callbacks(Looper looper) {\n            super(looper);\n        }\n\n        public void register(IPackageInstallerCallback callback, int userId) {\n            mCallbacks.register(callback, new VUserHandle(userId));","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/asLody/VirtualApp/blob/666fefcb5d3f39cc944001c3457c38ffd6544c87/VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/installer/VPackageInstallerService.java#L252-L288","documentation":"allocateSessionIdLocked picks a random positive int for a new install session and retries up to 32 times to find an ID not already used in mSessions. If all 32 attempts collide, it throws IllegalStateException(\"Failed to allocate session ID\"). With the full int range this practically only happens when the session map is saturated or buggy.","triggerScenarios":"createSessionInternal is invoked when mSessions already holds a very large number of live sessions, or a pathological random seed makes 32 consecutive collisions with existing IDs; also reachable if sessions are leaked (never abandoned/removed) over a long-lived host process.","commonSituations":"A VA host process that installs thousands of APKs without cleaning up leaked sessions; repeated createSession calls that never commit or abandon, filling the in-memory map; an RNG misconfiguration making nextInt degenerate.","solutions":["Audit the install flow: ensure every created session is eventually committed or abandoned so entries are removed from mSessions","Restart the VA/installer service process to clear the leaked session table, then retry the install","Serialize createSession calls or cap concurrent installs so the session map cannot grow unbounded","Update/patch the allocator to expand retries or use a monotonic counter instead of random IDs"],"exampleFix":"// before\nint id = installer.createSession(params); // can throw IllegalStateException after 32 collisions\n// after\ntry {\n    int id = installer.createSession(params);\n} catch (IllegalStateException e) {\n    // session table saturated: clean up stale sessions / restart installer, then retry\n    retryInstallAfterCleanup();\n}","handlingStrategy":"try-catch","validationCode":"// if the API exposes it, check session pressure first\nList<PackageInstaller.SessionInfo> live = installer.getAllSessions();\nif (live != null && live.size() > 500) { cleanupStaleSessions(); }","typeGuard":null,"tryCatchPattern":"try {\n    sessionId = installer.createSession(params);\n} catch (IllegalStateException e) {\n    restartInstallerService(); // clear leaked session table\n    sessionId = installer.createSession(params);\n}","preventionTips":["Always commit or abandon every created session","Cap concurrent installs and queue the rest","Monitor long-lived host processes for session leaks","Prefer deterministic single-threaded session creation in hot paths"],"tags":["android","package-installer","state-error","session-id","virtualapp"],"backgroundTag":"internal-invariant-violation","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"}