{"record":{"id":"b18dadbcd265d640","repo":"symfony/symfony","slug":"argument-beta-provided-to-s-get-must-be-a","errorCode":null,"errorMessage":"Argument \"$beta\" provided to \"%s::get()\" must be a positive number, %f given.","messagePattern":"Argument \"\\$beta\" provided to \"(.+?)::get\\(\\)\" must be a positive number, (.+?) given\\.","errorType":"exception","errorClass":"Symfony\\Component\\Cache\\Exception\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Component/Cache/Traits/ContractsTrait.php","lineNumber":65,"sourceCode":"            if (\\in_array(\\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {\n                $this->setCallbackWrapper(null);\n            }\n        }\n\n        if (null !== $callbackWrapper && !$callbackWrapper instanceof \\Closure) {\n            $callbackWrapper = $callbackWrapper(...);\n        }\n\n        $previousWrapper = $this->callbackWrapper;\n        $this->callbackWrapper = $callbackWrapper ?? static fn (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \\Closure $setMetadata, ?LoggerInterface $logger, ?float $beta = null) => $callback($item, $save);\n\n        return $previousWrapper;\n    }\n\n    private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null): mixed\n    {\n        if (0 > $beta ??= 1.0) {\n            throw new InvalidArgumentException(\\sprintf('Argument \"$beta\" provided to \"%s::get()\" must be a positive number, %f given.', static::class, $beta));\n        }\n\n        static $setMetadata;\n\n        $setMetadata ??= \\Closure::bind(\n            static function (CacheItem $item, float $startTime, ?array &$metadata) {\n                if ($item->expiry > $endTime = microtime(true)) {\n                    $item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry;\n                    $item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));\n                } else {\n                    unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME], $metadata[CacheItem::METADATA_TAGS]);\n                }\n            },\n            null,\n            CacheItem::class\n        );\n\n        $this->callbackWrapper ??= LockRegistry::compute(...);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Component/Cache/Traits/ContractsTrait.php#L47-L83","documentation":"doGet() implements stochastic early expiration: $beta weights how early a cached item is recomputed to avoid stampedes. beta defaults to 1.0 and any value below 0 is meaningless (it would never expire), so Symfony rejects it. The message interpolates the offending float and the concrete class via static::class.","triggerScenarios":"Calling $cache->get('key', $cb, -1) explicitly; passing beta computed from arithmetic that can go negative, e.g. $cache->get('k', $cb, $ttl - $now).","commonSituations":"Misreading beta as 'seconds of early expiration' and passing a negative delta; copying tutorial code that uses -1 to mean 'disable'.","solutions":["Pass beta >= 0; use 0.0 to disable early expiration, or omit it to accept the default 1.0.","Clamp computed beta: max(0.0, $computedBeta).","If you want indefinite lifetime, set it on the item via expiresAfter/expiresAt inside the callback, not via beta."],"exampleFix":"// before\n$cache->get('k', $cb, $grace - $now); // can be negative\n\n// after\n$cache->get('k', $cb, max(0.0, $grace - $now));","handlingStrategy":"validation","validationCode":"$beta = max(0.0, (float) $beta);\n$cache->get('key', $cb, $beta);","typeGuard":"function validBeta(float $beta): bool { return $beta >= 0.0; }","tryCatchPattern":"try { $cache->get('k', $cb, $beta); }\ncatch (\\Symfony\\Component\\Cache\\Exception\\InvalidArgumentException $e) {\n    // retry with default beta\n    return $cache->get('k', $cb);\n}","preventionTips":["Treat beta as a non-negative weight (0 disables early expiration).","Clamp computed beta values to >= 0.","Document beta semantics for teammates to prevent misuse."],"tags":["psr-6","validation","cache","numeric"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}