ellite/Wallos · error · InvalidArgumentException

Invalid "digits" parameter.

Error message

Invalid "digits" parameter.

What it means

This is a validation guard inside OTPHP's ParameterTrait: getDigits() fetches the 'digits' parameter from the OTP parameters array and throws InvalidArgumentException when it is absent, not an integer, or not strictly greater than 0. It fires when code reads the digit count of an OTP whose 'digits' parameter was never set (or was set to an invalid value, e.g. via setParameter) — typically when an object was built from a malformed provisioning URI missing the digits claim. Fix by setting a positive integer digit count (e.g. 6 or 8) before calling getDigits().

Solutions

  1. Pass a valid positive int (commonly 6 or 8) to TOTP::create($secret, null, 'sha1', 6).
  2. Cast config/DB values: (int) $digits and check $digits > 0 before use.
  3. Fix the provisioning URI's digits= query parameter to a positive integer.
  4. Guard: if (!is_int($digits) || $digits <= 0) { normalize before constructing the OTP object. }

Example fix

// before
$totp->setParameter('digits', '6'); // string from config
// after
$digits = (int) $config['digits'];
$totp->setParameter('digits', $digits > 0 ? $digits : 6);
Defensive patterns

Strategy: validation

Validate before calling

$digits = (int) ($config['digits'] ?? 6);
if ($digits <= 0) {
    $digits = 6;
}
$totp->setParameter('digits', $digits);

Type guard

function normalizeDigits(mixed $value): int {
    return is_int($value) && $value > 0 ? $value : 6;
}

Try / catch

try {
    $code = $otp->now();
} catch (InvalidArgumentException $e) {
    log_error('Invalid OTP parameters', ['exception' => $e->getMessage()]);
    throw new OtpConfigurationException($e);
}

Prevention

When it happens

Trigger: Setting digits to 0, a negative number, or a numeric string (e.g. from JSON/URI parsing '6'), then calling at()/now()/verify() which reads getDigits(). Note the parameter map may normalize some values, but raw invalid ints reach this check.

Common situations: Loading a provisioning URI with digits=0 or non-numeric digits; config values stored as strings in DB; custom digits like 3 or 20 rejected upstream but 0/-1 slipping here.

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 ellite/Wallos@52820e87ca (2026-09-13). Data as JSON: /api/errors/1b442ef2dc27a8b4. Report an issue: GitHub.

Appendix: source

Thrown at libs/OTPHP/ParameterTrait.php:88

    public function setIssuer(string $issuer): void
    {
        $this->setParameter('issuer', $issuer);
    }

    public function isIssuerIncludedAsParameter(): bool
    {
        return $this->issuer_included_as_parameter;
    }

    public function setIssuerIncludedAsParameter(bool $issuer_included_as_parameter): void
    {
        $this->issuer_included_as_parameter = $issuer_included_as_parameter;
    }

    public function getDigits(): int
    {
        $value = $this->getParameter('digits');
        (is_int($value) && $value > 0) || throw new InvalidArgumentException('Invalid "digits" parameter.');

        return $value;
    }

    public function getDigest(): string
    {
        $value = $this->getParameter('algorithm');
        (is_string($value) && $value !== '') || throw new InvalidArgumentException('Invalid "algorithm" parameter.');

        return $value;
    }

    public function hasParameter(string $parameter): bool
    {
        return array_key_exists($parameter, $this->parameters);
    }

    public function getParameter(string $parameter): mixed

View on GitHub (pinned to 52820e87ca)