{"record":{"id":"812990ee7a4848fe","repo":"beemdevelopment/Aegis","slug":"secret-cannot-be-empty","errorCode":null,"errorMessage":"Secret cannot be empty","messagePattern":"Secret cannot be empty","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java","lineNumber":751,"sourceCode":"            }\n        }\n\n        int digits;\n        try {\n            digits = Integer.parseInt(_textDigits.getText().toString());\n        } catch (NumberFormatException e) {\n            throw new ParseException(\"Digits is not an integer.\");\n        }\n\n        byte[] secret;\n        try {\n            String secretString = new String(EditTextHelper.getEditTextChars(_textSecret));\n\n            secret = (lowerCasedType.equals(MotpInfo.ID)) ?\n                    Hex.decode(secretString) : GoogleAuthInfo.parseSecret(secretString);\n\n            if (secret.length == 0) {\n                throw new ParseException(\"Secret cannot be empty\");\n            }\n        } catch (EncodingException e) {\n            String exceptionMessage = (lowerCasedType.equals(MotpInfo.ID)) ?\n                    \"Secret is not valid hexadecimal\" : \"Secret is not valid base32.\";\n\n            throw new ParseException(exceptionMessage);\n        }\n\n        OtpInfo info;\n        try {\n            switch (type.toLowerCase(Locale.ROOT)) {\n                case TotpInfo.ID:\n                    info = new TotpInfo(secret, algo, digits, parsePeriod());\n                    break;\n                case SteamInfo.ID:\n                    info = new SteamInfo(secret, algo, digits, parsePeriod());\n                    break;\n                case HotpInfo.ID:","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java#L733-L769","documentation":"After decoding the secret (hex for MOTP, base32 via GoogleAuthInfo.parseSecret otherwise), EditEntryActivity.parseEntry() throws this ParseException when the decoded byte array has length 0. A zero-length secret cannot produce OTP codes, so Aegis rejects it at save time.","triggerScenarios":"Saving an entry whose secret text decodes successfully but yields an empty byte array — e.g. an empty/whitespace-only base32 string or an empty hex string for MOTP.","commonSituations":"Pasting a placeholder or blank secret, or a secret consisting only of base32 padding characters that decode to zero bytes.","solutions":["Enter the real base32 secret from your provider (for MOTP, the hex secret)","Verify the pasted secret is complete and not a placeholder like 'AAAA' padding only","Re-scan or re-copy the provisioning secret and save again"],"exampleFix":"// before\nsecretField.setText(\"====\"); // decodes to zero bytes\n// after\nsecretField.setText(\"JBSWY3DPEHPK3PXP\");","handlingStrategy":"validation","validationCode":"String secret = new String(EditTextHelper.getEditTextChars(_textSecret)).trim();\nif (secret.isEmpty()) {\n    _textSecretLayout.setError(\"Secret is required\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    saveEntry();\n} catch (ParseException e) {\n    if (\"Secret cannot be empty\".equals(e.getMessage())) {\n        _textSecretLayout.setError(\"Secret decodes to empty — re-enter it\");\n    }\n}","preventionTips":["Decode-validate the secret client-side before saving","Reject secrets made only of padding/placeholder characters","Keep leading/trailing handling explicit (trim spaces, not base32 chars)"],"tags":["android","validation","otp","empty-secret"],"backgroundTag":"empty-required-field","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"}