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
- Pass a valid positive int (commonly 6 or 8) to TOTP::create($secret, null, 'sha1', 6).
- Cast config/DB values: (int) $digits and check $digits > 0 before use.
- Fix the provisioning URI's digits= query parameter to a positive integer.
- 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
- Cast digits from config/DB/URIs to int before use
- Allow-list acceptable digit counts (6, 8) at the config layer
- Fix digits= values in provisioning URIs to positive integers
- Round-trip test: build OTP -> export URI -> re-import and compare codes
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
- Invalid "counter" parameter.
- Label must not contain a colon.
- Unsupported " " OTP type
- The counter must be at least 0.
- Counter must be at least 0.
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): mixedView on GitHub (pinned to 52820e87ca)