{"record":{"id":"6656e666ab45141d","repo":"beemdevelopment/Aegis","slug":"host-not-present-in-uri-s","errorCode":null,"errorMessage":"Host not present in URI: %s","messagePattern":"Host not present in URI: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java","lineNumber":71,"sourceCode":"            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\n        OtpInfo info;\n        String issuer = \"\";\n        try {\n            String type = (scheme.equals(MotpInfo.SCHEME)) ? MotpInfo.ID : uri.getHost();\n            if (type == null) {\n                throw new GoogleAuthInfoException(uri, String.format(\"Host not present in URI: %s\", uri.toString()));\n            }\n\n            switch (type) {\n                case \"totp\":\n                    TotpInfo totpInfo = new TotpInfo(secret);\n                    String period = uri.getQueryParameter(\"period\");\n                    if (period != null) {\n                        totpInfo.setPeriod(Integer.parseInt(period));\n                    }\n                    info = totpInfo;\n                    break;\n                case \"steam\":\n                    SteamInfo steamInfo = new SteamInfo(secret);\n                    period = uri.getQueryParameter(\"period\");\n                    if (period != null) {\n                        steamInfo.setPeriod(Integer.parseInt(period));\n                    }\n                    info = steamInfo;","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/otp/GoogleAuthInfo.java#L53-L89","documentation":"Generic validation guard in parseUri(Uri): when the URI's type segment (host) does not map to a known OTP type such as totp/hotp/steam/motp, the code falls through to a default branch that reports the unrecognized host value. It fires on otpauth URIs with a wrong or missing type, e.g. otpauth://foo/...","triggerScenarios":"parseUri(Uri) with a URI like otpauth://?secret=... (no host component), e.g. otpauth://totp written without the host or a malformed scheme-specific part.","commonSituations":"Hand-written otpauth URIs, QR generators emitting otpauth:///label forms, or strings where the type was stripped during transfer.","solutions":["Include the OTP type as the URI host: otpauth://totp/... or otpauth://hotp/...","Re-generate the QR/URI with a standard generator library","Validate the URI contains a known host before importing"],"exampleFix":"// before\nString uri = \"otpauth://?secret=JBSWY3DPEHPK3PXP\";\n// after\nString uri = \"otpauth://totp/Example:alice?secret=JBSWY3DPEHPK3PXP\";","handlingStrategy":"validation","validationCode":"if (uri.getHost() == null) throw new IllegalArgumentException(\"otpauth URI missing type host\");","typeGuard":"boolean hasOtpType(Uri u) { return u.getHost() != null; }","tryCatchPattern":"try { return GoogleAuthInfo.parseUri(uri); } catch (GoogleAuthInfoException e) { showMalformedUriError(uri); return null; }","preventionTips":["Always format otpauth URIs as otpauth://<type>/<label>?params","Use a maintained otpauth URI generator library","Preview/validate URIs in unit tests before shipping QR generation"],"tags":["android","otp","uri","missing-host"],"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"}