{"record":{"id":"e35a894a35736898","repo":"beemdevelopment/Aegis","slug":"unsupported-otp-type-e35a89","errorCode":null,"errorMessage":"unsupported otp type: ","messagePattern":"unsupported otp type: ","errorType":"error_code","errorClass":"OtpInfoException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java","lineNumber":138,"sourceCode":"\n            switch (type) {\n                case TotpInfo.ID:\n                    info = new TotpInfo(secret, algo, digits, obj.getInt(\"period\"));\n                    break;\n                case SteamInfo.ID:\n                    info = new SteamInfo(secret, algo, digits, obj.getInt(\"period\"));\n                    break;\n                case HotpInfo.ID:\n                    info = new HotpInfo(secret, algo, digits, obj.getLong(\"counter\"));\n                    break;\n                case YandexInfo.ID:\n                    info = new YandexInfo(secret, obj.getString(\"pin\"));\n                    break;\n                case MotpInfo.ID:\n                    info = new MotpInfo(secret, obj.getString(\"pin\"));\n                    break;\n                default:\n                    throw new OtpInfoException(\"unsupported otp type: \" + type);\n            }\n        } catch (EncodingException | JSONException e) {\n            throw new OtpInfoException(e);\n        }\n\n        return info;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }\n        if (!(o instanceof OtpInfo)) {\n            return false;\n        }\n\n        OtpInfo info = (OtpInfo) o;","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java#L120-L156","documentation":"OtpInfo.fromJson dispatches on the OTP type string (TOTP, HOTP, Steam, Yandex, Motp, etc.) and throws when the stored type is not one of the supported constants. It happens while deserializing an entry from JSON (vault or import).","triggerScenarios":"Deserializing an entry whose JSON 'type' field is absent, misspelled, or from a newer/older Aegis version supporting types this build does not know; calling OtpInfo.fromJson(type, obj) directly with an unknown type.","commonSituations":"Importing vaults or backups from other apps or newer Aegis versions, manually edited vault JSON with a typo in 'type', downgraded Aegis build opening a vault created by a newer version.","solutions":["Update Aegis to the latest version so all supported otp types are recognized","Inspect the entry's JSON 'type' field and correct it to a supported value (TOTP, HOTP, STEAM, YANDEX, MOTP)","Check for typos/case mismatches in the type string before calling fromJson","Wrap fromJson in try-catch on OtpInfoException and skip/handle the unrecognized entry instead of failing the whole import"],"exampleFix":"// before\nOtpInfo info = OtpInfo.fromJson(obj.getString(\"type\"), obj); // throws for unknown type\n// after\nString type = obj.optString(\"type\", \"\");\nif (type.isEmpty() || !SUPPORTED_TYPES.contains(type)) {\n    Log.w(TAG, \"Skipping entry with unsupported type: \" + type);\n    return null;\n}\nOtpInfo info = OtpInfo.fromJson(type, obj);","handlingStrategy":"try-catch","validationCode":"Set<String> supported = Set.of(TotpInfo.ID, HotpInfo.ID, SteamInfo.ID, YandexInfo.ID, MotpInfo.ID);\nif (!supported.contains(type)) {\n    Log.w(TAG, \"Unsupported OTP type: \" + type);\n    return null;\n}","typeGuard":"boolean isSupportedOtpType(String t) {\n    return TotpInfo.ID.equals(t) || HotpInfo.ID.equals(t)\n        || SteamInfo.ID.equals(t) || YandexInfo.ID.equals(t) || MotpInfo.ID.equals(t);\n}","tryCatchPattern":"try {\n    return OtpInfo.fromJson(type, obj);\n} catch (OtpInfoException e) {\n    Log.w(TAG, \"Skipping entry with unsupported type: \" + type, e);\n    return null;\n}","preventionTips":["Keep Aegis updated before importing vaults from newer versions","Validate the 'type' field against known IDs before deserialization","Handle unknown entries gracefully instead of aborting the whole import","Never hand-edit vault JSON type fields without verifying accepted values"],"tags":["otp","deserialization","unsupported-type","android"],"backgroundTag":"invalid-enum-value","analyzedSha":"d6f4e5925a97e4e91593f1542085eae03432a759","analyzedAt":"2026-09-08T00:46:31.111Z","contentChangedAt":"2026-09-08T00:46:31.111Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}