{"record":{"id":"e0fe24a6594c9940","repo":"MuntashirAkon/AppManager","slug":"alias-alias-exists","errorCode":null,"errorMessage":"Alias ${alias} exists.","messagePattern":"Alias (.+?) exists\\.","errorType":"exception","errorClass":"KeyStoreException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java","lineNumber":287,"sourceCode":"        String encryptedPass = getEncryptedPassword(mContext, password);\n        if (encryptedPass == null) {\n            mAmKeyStore.deleteEntry(alias);\n            throw new KeyStoreException(\"Password for \" + alias + \" could not be saved.\");\n        }\n        sSharedPreferences.edit().putString(prefAlias, encryptedPass).apply();\n        try (OutputStream is = new FileOutputStream(AM_KEYSTORE_FILE)) {\n            mAmKeyStore.store(is, password);\n            Utils.clearChars(password);\n            Utils.clearChars(password);\n        }\n    }\n\n    public void addSecretKey(String alias, @NonNull SecretKey secretKey, boolean isOverride)\n            throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {\n        // Check existence of this alias in system preferences, this should be unique\n        String prefAlias = getPrefAlias(alias);\n        if (sSharedPreferences.contains(prefAlias) && mAmKeyStore.containsAlias(alias)) {\n            if (!isOverride) throw new KeyStoreException(\"Alias \" + alias + \" exists.\");\n            else Log.w(TAG, \"Alias %s exists.\", alias);\n        }\n        char[] password = getAmKeyStorePassword();\n        mAmKeyStore.setEntry(alias, new KeyStore.SecretKeyEntry(secretKey), new KeyStore.PasswordProtection(password));\n        String encryptedPass = getEncryptedPassword(mContext, password);\n        if (encryptedPass == null) {\n            mAmKeyStore.deleteEntry(alias);\n            throw new KeyStoreException(\"Password for \" + alias + \" could not be saved.\");\n        }\n        sSharedPreferences.edit().putString(prefAlias, encryptedPass).apply();\n        try (OutputStream is = new FileOutputStream(AM_KEYSTORE_FILE)) {\n            mAmKeyStore.store(is, password);\n        } finally {\n            Utils.clearChars(password);\n            Utils.clearChars(password);\n        }\n    }\n","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java#L269-L305","documentation":"addSecretKey enforces unique aliases: if the alias is already registered in both shared preferences and the AM keystore and isOverride is false, a KeyStoreException is thrown. With isOverride=true the existing key is silently replaced instead.","triggerScenarios":"Calling addSecretKey(alias, secretKey, false) when the alias already exists in both sSharedPreferences and mAmKeyStore — typically during migrateKeyStore when the target key was already migrated.","commonSituations":"Running keystore migration twice; re-importing a key that already exists; concurrent processes adding the same alias.","solutions":["Pass isOverride=true if the existing key should be replaced","Check mAmKeyStore.containsAlias(alias)/preference first and skip adding when present","Use a different alias for the new key"],"exampleFix":"// before\nksManager.addSecretKey(alias, secretKey, false);\n// after\nif (!ksManager.containsAlias(alias)) {\n    ksManager.addSecretKey(alias, secretKey, false);\n} else {\n    ksManager.addSecretKey(alias, secretKey, true); // intentional override\n}","handlingStrategy":"validation","validationCode":"String prefAlias = KeyStoreManager.getPrefAlias(alias);\nboolean exists = prefs.contains(prefAlias) && ksManager.containsAlias(alias);\nif (exists && !allowOverride) {\n    alias = alias + \"-\" + System.currentTimeMillis(); // unique alias\n}","typeGuard":null,"tryCatchPattern":"try {\n    ksManager.addSecretKey(alias, secretKey, false);\n} catch (KeyStoreException e) {\n    // alias already exists; retry with override or new alias\n    ksManager.addSecretKey(alias, secretKey, true);\n}","preventionTips":["Make migration idempotent: skip aliases that already exist","Pass isOverride=true deliberately, not by default","Generate unique aliases for one-off keys"],"tags":["keystore","duplicate-key","android"],"backgroundTag":"file-already-exists","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}