{"record":{"id":"95edd84e58ed7984","repo":"beemdevelopment/Aegis","slug":"unsupported-protocol-s","errorCode":null,"errorMessage":"Unsupported protocol: %s","messagePattern":"Unsupported protocol: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java","lineNumber":47,"sourceCode":"\n    public GoogleAuthInfo(OtpInfo info, String accountName, String issuer) {\n        _info = info;\n        _accountName = accountName;\n        _issuer = issuer;\n    }\n\n    public static GoogleAuthInfo parseUri(String s) throws GoogleAuthInfoException {\n        Uri uri = Uri.parse(s);\n        if (uri == null) {\n            throw new GoogleAuthInfoException(uri, String.format(\"Bad URI format: %s\", s));\n        }\n        return GoogleAuthInfo.parseUri(uri);\n    }\n\n    public static GoogleAuthInfo parseUri(Uri uri) throws GoogleAuthInfoException {\n        String scheme = uri.getScheme();\n        if (scheme == null || !(scheme.equals(SCHEME) || scheme.equals(MotpInfo.SCHEME))) {\n            throw new GoogleAuthInfoException(uri, String.format(\"Unsupported protocol: %s\", scheme));\n        }\n\n        // 'secret' is a required parameter\n        String encodedSecret = uri.getQueryParameter(\"secret\");\n        if (encodedSecret == null) {\n            throw new GoogleAuthInfoException(uri, \"Parameter 'secret' is not present\");\n        }\n\n        byte[] secret;\n        try {\n            secret = (scheme.equals(MotpInfo.SCHEME)) ? Hex.decode(encodedSecret) : parseSecret(encodedSecret);\n        } catch (EncodingException e) {\n            throw new GoogleAuthInfoException(uri, \"Bad secret\", e);\n        }\n        if (secret.length == 0) {\n            throw new GoogleAuthInfoException(uri, \"Secret is empty\");\n        }\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java#L29-L65","documentation":"Thrown by GoogleAuthInfo.parseUri(Uri) when the otpauth/motp URI's scheme is null or not one of the supported schemes (\"otpauth\" or MotpInfo.SCHEME). It fires when a user imports or pastes a malformed or non-2FA URI, acting as the protocol validation gate before any OTP parameters are read.","triggerScenarios":"GoogleAuthInfo.parseUri(Uri) called with a URI whose getScheme() is null or not 'otpauth'/'motp' (e.g. https://, http://, or a scheme-less string).","commonSituations":"Importing an arbitrary web link by mistake, scanning a non-2FA QR code (URL, wifi config, vcard), or passing an already-decoded text payload that isn't an otpauth URI.","solutions":["Check uri.getScheme() equals \"otpauth\" (or \"motp\") before calling parseUri","Ensure the QR scanner returns the raw URI text without stripping the scheme","Catch GoogleAuthInfoException and tell the user the code is not a supported 2FA URI"],"exampleFix":"// before\nUri uri = Uri.parse(scanned);\nGoogleAuthInfo info = GoogleAuthInfo.parseUri(uri);\n// after\nUri uri = Uri.parse(scanned);\nif (uri.getScheme() != null && uri.getScheme().equals(\"otpauth\")) {\n    GoogleAuthInfo info = GoogleAuthInfo.parseUri(uri);\n} else {\n    throw new GoogleAuthInfoException(uri, \"Not an otpauth URI\");\n}","handlingStrategy":"validation","validationCode":"Uri uri = Uri.parse(s); if (uri.getScheme() == null || !(uri.getScheme().equals(\"otpauth\") || uri.getScheme().equals(\"motp\"))) return null;","typeGuard":"boolean isOtpUri(Uri u) { String s = u.getScheme(); return s != null && (s.equals(\"otpauth\") || s.equals(\"motp\")); }","tryCatchPattern":"try { return GoogleAuthInfo.parseUri(uri); } catch (GoogleAuthInfoException e) { Log.w(TAG, \"Unsupported URI: \" + uri); return null; }","preventionTips":["Check scheme equals otpauth before parsing","Ensure QR scanner output preserves the full URI","Filter incoming intents by URI scheme"],"tags":["android","otp","uri-scheme","unsupported-protocol"],"backgroundTag":"invalid-url-format","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"}