{"record":{"id":"2254a7f067a6eba8","repo":"ellite/Wallos","slug":"invalid-period-parameter","errorCode":null,"errorMessage":"Invalid \"period\" parameter.","messagePattern":"Invalid \"period\" parameter\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"libs/OTPHP/TOTP.php","lineNumber":73,"sourceCode":"    {\n        $totp = new self($secret, $clock);\n        $totp->setPeriod(self::DEFAULT_PERIOD);\n        $totp->setDigest(self::DEFAULT_DIGEST);\n        $totp->setDigits(self::DEFAULT_DIGITS);\n        $totp->setEpoch(self::DEFAULT_EPOCH);\n\n        return $totp;\n    }\n\n    public static function generate(?ClockInterface $clock = null): self\n    {\n        return self::createFromSecret(self::generateSecret(), $clock);\n    }\n\n    public function getPeriod(): int\n    {\n        $value = $this->getParameter('period');\n        (is_int($value) && $value > 0) || throw new InvalidArgumentException('Invalid \"period\" parameter.');\n\n        return $value;\n    }\n\n    public function getEpoch(): int\n    {\n        $value = $this->getParameter('epoch');\n        (is_int($value) && $value >= 0) || throw new InvalidArgumentException('Invalid \"epoch\" parameter.');\n\n        return $value;\n    }\n\n    public function expiresIn(): int\n    {\n        $period = $this->getPeriod();\n\n        return $period - ($this->clock->now()->getTimestamp() % $this->getPeriod());\n    }","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/ellite/Wallos/blob/52820e87ca5a6e105fdbb7f1c0c681bc0cfee2fd/libs/OTPHP/TOTP.php#L55-L91","documentation":"TOTP::getPeriod() reads the 'period' parameter and validates it is a positive integer before returning it. If the parameter is missing, not an int, or <= 0, the TOTP cannot compute timecodes, so this InvalidArgumentException is thrown.","triggerScenarios":"Calling getPeriod() (or expiresIn/verify/getProvisioningUri/timecode which call it) on a TOTP whose 'period' was never set or was set to a non-int/zero value, e.g. via setParameter('period', '30') with a string, or through a partially constructed object.","commonSituations":"Loading a provisioning URI whose query lacks a valid period; constructing TOTP manually and forgetting setParameter('period', 30); config value coming as a numeric string from env/INI which passed the map but stored oddly, or was bypassed entirely.","solutions":["Set the period explicitly: $totp->setParameter('period', 30) before use","Ensure the value is a real int (cast strings: (int)$config['period'])","If parsing a URI, confirm the otpauth URI has a numeric period > 0 in the query string"],"exampleFix":"// before\n$totp->setParameter('period', '30');\n$totp->verify($code); // may hit invalid period\n// after\n$totp->setParameter('period', (int) $config['period']);","handlingStrategy":"validation","validationCode":"if (!isset($params['period']) || !is_int($params['period']) || $params['period'] <= 0) {\n    $totp->setParameter('period', 30);\n}","typeGuard":"function hasValidPeriod($totp): bool {\n    $v = $totp->getParameters()['period'] ?? null;\n    return is_int($v) && $v > 0;\n}","tryCatchPattern":"try {\n    $period = $totp->getPeriod();\n} catch (\\InvalidArgumentException $e) {\n    $totp->setParameter('period', 30);\n    $period = $totp->getPeriod();\n}","preventionTips":["Cast period from config/env to int before setting","Always create TOTP via TOTP::createFromSecret so defaults apply","Validate provisioning URIs contain a positive integer period"],"tags":["php","totp","parameter-validation"],"backgroundTag":"invalid-config-value","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"}