{"record":{"id":"79f7ae3241f6d757","repo":"ratchetphp/Ratchet","slug":"expected-instance-of-ratchet-websocket","errorCode":null,"errorMessage":"Expected instance of \\Ratchet\\WebSocket\\MessageComponentInterface or \\Ratchet\\MessageComponentInterface","messagePattern":"Expected instance of \\\\Ratchet\\\\WebSocket\\\\MessageComponentInterface or \\\\Ratchet\\\\MessageComponentInterface","errorType":"validation","errorClass":"UnexpectedValueException","httpStatus":null,"severity":"error","filePath":"src/Ratchet/WebSocket/WsServer.php","lineNumber":79,"sourceCode":"     * @var \\Closure\n     */\n    private $msgCb;\n\n    /**\n     * @param \\Ratchet\\WebSocket\\MessageComponentInterface|\\Ratchet\\MessageComponentInterface $component Your application to run with WebSockets\n     * @note If you want to enable sub-protocols have your component implement WsServerInterface as well\n     */\n    public function __construct(ComponentInterface $component) {\n        if ($component instanceof MessageComponentInterface) {\n            $this->msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {\n                $this->delegate->onMessage($conn, $msg);\n            };\n        } elseif ($component instanceof DataComponentInterface) {\n            $this->msgCb = function(ConnectionInterface $conn, MessageInterface $msg) {\n                $this->delegate->onMessage($conn, $msg->getPayload());\n            };\n        } else {\n            throw new \\UnexpectedValueException('Expected instance of \\Ratchet\\WebSocket\\MessageComponentInterface or \\Ratchet\\MessageComponentInterface');\n        }\n\n        if (bin2hex('✓') !== 'e29c93') {\n            throw new \\DomainException('Bad encoding, unicode character ✓ did not match expected value. Ensure charset UTF-8 and check ini val mbstring.func_autoload');\n        }\n\n        $this->delegate    = $component;\n        $this->connections = new \\SplObjectStorage;\n\n        $this->closeFrameChecker   = new CloseFrameChecker;\n\n        if (self::isRFC6455v03()) {\n            $this->handshakeNegotiator = new ServerNegotiator(new RequestVerifier);\n        } else {\n            $this->handshakeNegotiator = new ServerNegotiator(new RequestVerifier, new HttpFactory);\n        }\n\n        $this->handshakeNegotiator->setStrictSubProtocolCheck(true);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/ratchetphp/Ratchet/blob/e621c6c40bf684bbbb877102416ad5303d05a9cc/src/Ratchet/WebSocket/WsServer.php#L61-L97","documentation":"WsServer's constructor requires the wrapped component to implement either Ratchet\\WebSocket\\MessageComponentInterface or Ratchet\\MessageComponentInterface; anything else (only implementing the lower-level DataComponentInterface or bare ComponentInterface) triggers an UnexpectedValueException. The message callbacks differ per interface, so WsServer refuses components it cannot dispatch messages to.","triggerScenarios":"new WsServer($component) where $component implements neither MessageComponentInterface variant — e.g. only IoServer/ DataComponentInterface methods, or a typo'd class missing the onMessage contract.","commonSituations":"Wrapping a raw ConnectionInterface-style component in WsServer; building a custom middleware chain where an inner component lacks the message interface; forgetting to implement onMessage/onClose/onError after refactoring.","solutions":["Make your application class implement Ratchet\\MessageComponentInterface (onOpen/onMessage/onClose/onError) — the common case.","Alternatively implement Ratchet\\WebSocket\\MessageComponentInterface if you need frame-level message metadata (e.g. subprotocols via WsServerInterface).","If you truly need raw data access, use DataComponentInterface with the appropriate lower-level server setup instead of WsServer."],"exampleFix":"// before\nclass Chat implements \\Ratchet\\ComponentInterface { /* no onMessage contract */ }\n$ws = new \\Ratchet\\WebSocket\\WsServer(new Chat());\n// after\nclass Chat implements \\Ratchet\\MessageComponentInterface {\n    public function onOpen(\\Ratchet\\ConnectionInterface $c) {}\n    public function onMessage(\\Ratchet\\ConnectionInterface $c, $msg) {}\n    public function onClose(\\Ratchet\\ConnectionInterface $c) {}\n    public function onError(\\Ratchet\\ConnectionInterface $c, \\Exception $e) {}\n}\n$ws = new \\Ratchet\\WebSocket\\WsServer(new Chat());","handlingStrategy":"type-guard","validationCode":"if (!($app instanceof \\Ratchet\\MessageComponentInterface) && !($app instanceof \\Ratchet\\WebSocket\\MessageComponentInterface)) {\n    throw new \\LogicException('Component passed to WsServer must implement a MessageComponentInterface');\n}\n$ws = new \\Ratchet\\WebSocket\\WsServer($app);","typeGuard":"function isWsCompatible($c): bool {\n    return $c instanceof \\Ratchet\\MessageComponentInterface || $c instanceof \\Ratchet\\WebSocket\\MessageComponentInterface;\n}","tryCatchPattern":"try {\n    $ws = new \\Ratchet\\WebSocket\\WsServer($app);\n} catch (\\UnexpectedValueException $e) {\n    // adapt the component before retrying\n    $ws = new \\Ratchet\\WebSocket\\WsServer(new ComponentAdapter($app));\n}","preventionTips":["Have app classes implement Ratchet\\MessageComponentInterface as the default choice.","Run a smoke test that constructs the full IoServer stack before deployment.","Check interface imports — two similarly named MessageComponentInterface classes exist under Ratchet\\ and Ratchet\\WebSocket\\."],"tags":["php","websocket","type-mismatch"],"backgroundTag":"type-mismatch","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"}