{"record":{"id":"e42f1bfa6f245d6b","repo":"ratchetphp/Ratchet","slug":"argument-4-serializer-expected-null-ratchet-session","errorCode":null,"errorMessage":"Argument #4 ($serializer) expected null|Ratchet\\Session\\Serialize\\HandlerInterface","messagePattern":"Argument #4 \\(\\$serializer\\) expected null\\|Ratchet\\\\Session\\\\Serialize\\\\HandlerInterface","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Ratchet/Session/SessionProvider.php","lineNumber":49,"sourceCode":"     * @var \\SessionHandlerInterface\n     */\n    protected $_null;\n\n    /**\n     * @var \\Ratchet\\Session\\Serialize\\HandlerInterface\n     */\n    protected $_serializer;\n\n    /**\n     * @param \\Ratchet\\Http\\HttpServerInterface            $app\n     * @param \\SessionHandlerInterface                     $handler\n     * @param array                                        $options\n     * @param ?\\Ratchet\\Session\\Serialize\\HandlerInterface $serializer\n     * @throws \\RuntimeException\n     */\n    public function __construct(HttpServerInterface $app, \\SessionHandlerInterface $handler, array $options = array(), $serializer = null) {\n        if ($serializer !== null && !$serializer instanceof HandlerInterface) { // manual type check to support legacy PHP < 7.1\n            throw new \\InvalidArgumentException('Argument #4 ($serializer) expected null|Ratchet\\Session\\Serialize\\HandlerInterface');\n        }\n        $this->_app     = $app;\n        $this->_handler = $handler;\n        $this->_null    = new NullSessionHandler;\n\n        ini_set('session.auto_start', 0);\n        ini_set('session.cache_limiter', '');\n        ini_set('session.use_cookies', 0);\n\n        $this->setOptions($options);\n\n        if (null === $serializer) {\n            $serialClass = __NAMESPACE__ . \"\\\\Serialize\\\\{$this->toClassCase(ini_get('session.serialize_handler'))}Handler\"; // awesome/terrible hack, eh?\n            if (!class_exists($serialClass)) {\n                throw new \\RuntimeException('Unable to parse session serialize handler');\n            }\n\n            $serializer = new $serialClass;","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/ratchetphp/Ratchet/blob/e621c6c40bf684bbbb877102416ad5303d05a9cc/src/Ratchet/Session/SessionProvider.php#L31-L67","documentation":"SessionProvider's constructor accepts an optional fourth argument $serializer that must be either null or an instance of Ratchet\\Session\\Serialize\\HandlerInterface. Because the library supports legacy PHP versions without nullable type hints, it performs a manual instanceof check instead of relying on the engine's type validation, and throws InvalidArgumentException itself when the value is neither null nor a HandlerInterface.","triggerScenarios":"Calling new SessionProvider($app, $handler, $options) with a fourth argument that is not null and does not implement Ratchet\\Session\\Serialize\\HandlerInterface — e.g. passing a plain object, a wrong serializer class, or a misordered argument (an array or string landing in position 4).","commonSituations":"Copy-pasted constructor calls with arguments in the wrong order; passing Symfony's own serializer or a custom session class that only implements \\SessionHandlerInterface; upgrades where a custom serializer class was refactored away from HandlerInterface.","solutions":["Pass null (or omit) as the fourth argument to let SessionProvider auto-detect the serializer from ini_get('session.serialize_handler').","Make the passed object implement Ratchet\\Session\\Serialize\\HandlerInterface (with the four methods: open, close, unserialize/serialize pair per interface).","Check the argument order of the constructor: ($app, $handler, $options, $serializer) and fix any shifted arguments.","Type-check the value before constructing: assert($serializer instanceof HandlerInterface || $serializer === null)."],"exampleFix":"// before\n$provider = new SessionProvider($app, $handler, [], new \\stdClass);\n// after\n$provider = new SessionProvider($app, $handler, [], null); // auto-detect\n// or implement Ratchet\\Session\\Serialize\\HandlerInterface in your custom class","handlingStrategy":"type-guard","validationCode":"if ($serializer !== null && !$serializer instanceof \\Ratchet\\Session\\Serialize\\HandlerInterface) {\n    throw new \\InvalidArgumentException('$serializer must be null or HandlerInterface');\n}\n$provider = new SessionProvider($app, $handler, $options, $serializer);","typeGuard":"function isValidSerializer($s): bool {\n    return $s === null || $s instanceof \\Ratchet\\Session\\Serialize\\HandlerInterface;\n}","tryCatchPattern":"try {\n    $provider = new SessionProvider($app, $handler, $options, $serializer);\n} catch (\\InvalidArgumentException $e) {\n    // fall back to auto-detected serializer\n    $provider = new SessionProvider($app, $handler, $options);\n}","preventionTips":["Pass null and let SessionProvider auto-detect unless you have a custom serializer.","Add a PHPDoc type ?HandlerInterface on your factory methods so static analysis catches wrong types.","Keep constructor argument order documented: ($app, $handler, $options, $serializer).","Run static analysis (PHPStan/Psalm) to catch non-HandlerInterface arguments."],"tags":["php","invalid-argument","session","constructor"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"e621c6c40bf684bbbb877102416ad5303d05a9cc","analyzedAt":"2026-09-16T00:13:27.878Z","contentChangedAt":"2026-09-16T00:13:27.878Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}