beemdevelopment/Aegis · error · ParseException

PIN must have a length of 4 digits.

Error message

PIN must have a length of 4 digits.

What it means

For MOTP-type entries, EditEntryActivity.parseEntry() additionally requires the PIN to be exactly 4 digits (Yandex accepts 4+). This ParseException is thrown when the PIN is 4 or more characters but not exactly 4, since the MOTP algorithm consumes a fixed 4-digit PIN.

Solutions

  1. Enter exactly 4 digits in the PIN field for MOTP entries
  2. Trim any extra characters from the PIN before saving
  3. Switch the entry type to Yandex if you need a longer PIN

Example fix

// before
pinField.setText("12345"); // MOTP
// after
pinField.setText("1234"); // MOTP
Defensive patterns

Strategy: validation

Validate before calling

if (type.equals("motp") && _textPin.length() != 4) {
    _textPinLayout.setError("MOTP PIN must be exactly 4 digits");
    return;
}

Try / catch

try {
    saveEntry();
} catch (ParseException e) {
    if ("PIN must have a length of 4 digits.".equals(e.getMessage())) {
        _textPinLayout.setError("MOTP PIN must be exactly 4 digits");
    }
}

Prevention

When it happens

Trigger: Saving an entry with type MotpInfo.ID while _textPin length is 5 or more (e.g. '12345'); the earlier min-length check passed but the exactly-4 check fails.

Common situations: Users entering a longer passcode for a MOTP entry, or pasting a PIN plus extra digits, not realizing MOTP mandates exactly 4 digits.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of beemdevelopment/Aegis@d6f4e5925a (2026-09-08). Data as JSON: /api/errors/d50fee029c4f9833. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java:732

        }
    }

    private VaultEntry parseEntry() throws ParseException {
        if (_textSecret.length() == 0) {
            throw new ParseException("Secret is a required field.");
        }

        String type = _dropdownType.getText().toString();
        String algo = _dropdownAlgo.getText().toString();
        String lowerCasedType = type.toLowerCase(Locale.ROOT);

        if (lowerCasedType.equals(YandexInfo.ID) || lowerCasedType.equals(MotpInfo.ID)) {
            int pinLength = _textPin.length();
            if (pinLength < 4) {
                throw new ParseException("PIN is a required field. Must have a minimum length of 4 digits.");
            }
            if (pinLength != 4 && lowerCasedType.equals(MotpInfo.ID)) {
                throw new ParseException("PIN must have a length of 4 digits.");
            }
        }

        int digits;
        try {
            digits = Integer.parseInt(_textDigits.getText().toString());
        } catch (NumberFormatException e) {
            throw new ParseException("Digits is not an integer.");
        }

        byte[] secret;
        try {
            String secretString = new String(EditTextHelper.getEditTextChars(_textSecret));

            secret = (lowerCasedType.equals(MotpInfo.ID)) ?
                    Hex.decode(secretString) : GoogleAuthInfo.parseSecret(secretString);

            if (secret.length == 0) {

View on GitHub (pinned to d6f4e5925a)