{"record":{"id":"649a808ca6e0822c","repo":"beemdevelopment/Aegis","slug":"secret-is-a-required-field","errorCode":null,"errorMessage":"Secret is a required field.","messagePattern":"Secret is a required field\\.","errorType":"validation","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java","lineNumber":719,"sourceCode":"        intent.putExtra(\"delete\", delete);\n\n        if (saveAndBackupVault()) {\n            setResult(RESULT_OK, intent);\n            finish();\n        }\n    }\n\n    private int parsePeriod() throws ParseException {\n        try {\n            return Integer.parseInt(_textPeriodCounter.getText().toString());\n        } catch (NumberFormatException e) {\n            throw new ParseException(\"Period is not an integer.\");\n        }\n    }\n\n    private VaultEntry parseEntry() throws ParseException {\n        if (_textSecret.length() == 0) {\n            throw new ParseException(\"Secret is a required field.\");\n        }\n\n        String type = _dropdownType.getText().toString();\n        String algo = _dropdownAlgo.getText().toString();\n        String lowerCasedType = type.toLowerCase(Locale.ROOT);\n\n        if (lowerCasedType.equals(YandexInfo.ID) || lowerCasedType.equals(MotpInfo.ID)) {\n            int pinLength = _textPin.length();\n            if (pinLength < 4) {\n                throw new ParseException(\"PIN is a required field. Must have a minimum length of 4 digits.\");\n            }\n            if (pinLength != 4 && lowerCasedType.equals(MotpInfo.ID)) {\n                throw new ParseException(\"PIN must have a length of 4 digits.\");\n            }\n        }\n\n        int digits;\n        try {","sourceCodeStart":701,"sourceCodeEnd":737,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java#L701-L737","documentation":"EditEntryActivity.parseEntry() checks that the secret text field is non-empty before building the VaultEntry. Aegis throws this ParseException when the user attempts to save an OTP entry without entering any secret, because an OTP entry without a secret cannot generate codes.","triggerScenarios":"Pressing save on the edit-entry screen while the Secret field has zero length (_textSecret.length() == 0); also occurs when pasting fails or the field is cleared after importing an entry with no secret.","commonSituations":"Manually adding a new 2FA account and forgetting to paste the base32 secret from the provider, or accidentally deleting the secret while editing an existing entry.","solutions":["Paste the OTP secret (base32 for TOTP/HOTP/Yandex, hexadecimal for MOTP) into the Secret field before saving","Re-copy the secret from the provider's setup key or QR provisioning URI","Cancel the edit if you did not intend to modify the secret"],"exampleFix":"// before\nsecretField.setText(\"\");\nsaveEntry();\n// after\nsecretField.setText(\"JBSWY3DPEHPK3PXP\");\nsaveEntry();","handlingStrategy":"validation","validationCode":"if (_textSecret.length() == 0) {\n    _textSecretLayout.setError(\"Secret is required\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    saveEntry();\n} catch (ParseException e) {\n    if (\"Secret is a required field.\".equals(e.getMessage())) {\n        _textSecretLayout.setError(\"Secret is required\");\n    }\n}","preventionTips":["Disable the save button until the secret field is non-empty","Show a required-field indicator on the secret input","When editing, keep the original secret unless the user explicitly replaces it"],"tags":["android","validation","otp","empty-input"],"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"}