beemdevelopment/Aegis · error · ParseException

Counter is not an integer.

Error message

Counter is not an integer.

What it means

For HOTP entries, EditEntryActivity.parseEntry() reads the counter from the period/counter field with Long.parseLong and wraps NumberFormatException in a ParseException. The HOTP counter must be a 64-bit integer, so empty or non-numeric input is rejected before constructing HotpInfo.

Solutions

  1. Enter a plain integer counter (e.g. 0) in the period/counter field before saving
  2. Retype the value to remove whitespace or separators like commas
  3. Use a value within signed 64-bit range (-9223372036854775808 to 9223372036854775807)

Example fix

// before
counterField.setText("1,000");
// after
counterField.setText("1000");
Defensive patterns

Strategy: validation

Validate before calling

String counter = _textPeriodCounter.getText().toString().trim();
if (!counter.matches("-?\\d+")) {
    _textPeriodCounterLayout.setError("HOTP counter must be an integer");
    return;
}

Try / catch

try {
    saveEntry();
} catch (ParseException e) {
    if ("Counter is not an integer.".equals(e.getMessage())) {
        _textPeriodCounterLayout.setError("Enter an integer counter");
    }
}

Prevention

When it happens

Trigger: Saving an HOTP entry while the counter field is empty, contains letters/decimals, or exceeds Long range; Long.parseLong throws NumberFormatException.

Common situations: Switching an entry from TOTP to HOTP without setting a counter, or pasting a counter value with formatting such as '1,000' or '0x1F'.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

            throw new ParseException(exceptionMessage);
        }

        OtpInfo info;
        try {
            switch (type.toLowerCase(Locale.ROOT)) {
                case TotpInfo.ID:
                    info = new TotpInfo(secret, algo, digits, parsePeriod());
                    break;
                case SteamInfo.ID:
                    info = new SteamInfo(secret, algo, digits, parsePeriod());
                    break;
                case HotpInfo.ID:
                    long counter;
                    try {
                        counter = Long.parseLong(_textPeriodCounter.getText().toString());
                    } catch (NumberFormatException e) {
                        throw new ParseException("Counter is not an integer.");
                    }
                    info = new HotpInfo(secret, algo, digits, counter);
                    break;
                case YandexInfo.ID:
                    info = new YandexInfo(secret, _textPin.getText().toString());
                    break;
                case MotpInfo.ID:
                    info = new MotpInfo(secret, _textPin.getText().toString());
                    break;
                default:
                    throw new RuntimeException(String.format("Unsupported OTP type: %s", type));
            }

            info.setDigits(digits);
            info.setAlgorithm(algo);
        } catch (OtpInfoException e) {
            throw new ParseException("The entered info is incorrect: " + e.getMessage());
        }

View on GitHub (pinned to d6f4e5925a)