{"record":{"id":"1a23aa6bfb5cb58b","repo":"ellite/Wallos","slug":"digits-must-be-at-least-1","errorCode":null,"errorMessage":"Digits must be at least 1.","messagePattern":"Digits must be at least 1\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"libs/OTPHP/ParameterTrait.php","lineNumber":171,"sourceCode":"                assert($value !== '');\n                $this->hasColon($value) === false || throw new InvalidArgumentException(\n                    'Label must not contain a colon.'\n                );\n\n                return $value;\n            },\n            'secret' => static fn (string $value): string => strtoupper(trim($value, '=')),\n            'algorithm' => static function (string $value): string {\n                $value = strtolower($value);\n                in_array($value, hash_algos(), true) || throw new InvalidArgumentException(sprintf(\n                    'The \"%s\" digest is not supported.',\n                    $value\n                ));\n\n                return $value;\n            },\n            'digits' => static function ($value): int {\n                $value > 0 || throw new InvalidArgumentException('Digits must be at least 1.');\n\n                return (int) $value;\n            },\n            'issuer' => function (string $value): string {\n                assert($value !== '');\n                $this->hasColon($value) === false || throw new InvalidArgumentException(\n                    'Issuer must not contain a colon.'\n                );\n\n                return $value;\n            },\n        ];\n    }\n\n    /**\n     * @param non-empty-string $value\n     */\n    private function hasColon(string $value): bool","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/ellite/Wallos/blob/52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd/libs/OTPHP/ParameterTrait.php#L153-L189","documentation":"The 'digits' entry of the parameter map coerces the assigned value and requires it to be strictly greater than 0. Assigning 0, a negative number, or a non-numeric value via setParameter('digits', ...) throws this InvalidArgumentException because an OTP code must have at least one digit.","triggerScenarios":"Calling setParameter('digits', 0) or setParameter('digits', -6); passing a string like 'abc' that compares non-numerically; passing null (null > 0 is false in loose comparison).","commonSituations":"Reading the digit count from user config or a database column that defaults to 0; parsing a provisioning URI with digits=0; a template variable left empty.","solutions":["Pass a positive integer, typically 6 or 8, to setParameter('digits', ...)","Validate/clamp the configured value with max(1, (int)$value) before assigning","Fix the upstream config or DB default that produced 0"],"exampleFix":"// before\n$otp->setParameter('digits', $config['otp_length'] ?? 0);\n// after\n$otp->setParameter('digits', max(1, (int)($config['otp_length'] ?? 6)));","handlingStrategy":"validation","validationCode":"$digits = (int)($config['digits'] ?? 6);\nif ($digits < 1) {\n    $digits = 6;\n}\n$otp->setParameter('digits', $digits);","typeGuard":null,"tryCatchPattern":"try {\n    $otp->setParameter('digits', $value);\n} catch (\\InvalidArgumentException $e) {\n    $otp->setParameter('digits', 6);\n}","preventionTips":["Clamp configured digit counts to 6 or 8","Cast env/config strings to int before assigning","Guard database defaults so they can never be 0"],"tags":["php","otp","value-out-of-range"],"backgroundTag":"value-out-of-range","analyzedSha":"52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd","analyzedAt":"2026-09-13T14:09:30.873Z","contentChangedAt":"2026-09-13T14:09:30.873Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}