ratchetphp/Ratchet · error · RuntimeException

A React Loop was not provided during instantiation

Error message

A React Loop was not provided during instantiation

What it means

IoServer::run() requires the React event loop that was bound to the server at construction time. This error signals that the IoServer instance was created without a LoopInterface (constructor received null) — typically by using new IoServer($app, $socket) directly instead of IoServer::factory(), which creates a loop automatically. run() cannot start the server because there is no loop to run; the guard converts a null-property condition into a clear configuration error.

Solutions

  1. Build the server with IoServer::factory($component, $port, $address), which constructs a React loop and socket automatically.
  2. If constructing manually, pass a loop: new IoServer($app, $socket, React\EventLoop\Loop::get()) or an explicit Factory::create() loop.
  3. Store the loop you pass to the socket server and reuse it for the IoServer so both share the same event loop instance.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/Ratchet/Server/IoServer.php:79 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of ratchetphp/Ratchet@e621c6c40b (2026-09-16). Data as JSON: /api/errors/5f6b2d9b925b8168. Report an issue: GitHub.

Appendix: source

Thrown at src/Ratchet/Server/IoServer.php:79

     * @return IoServer
     */
    public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0') {
        // prefer default Loop (reactphp/event-loop v1.2+) over legacy \React\EventLoop\Factory
        $loop = class_exists('React\EventLoop\Loop') ? Loop::get() : LegacyLoopFactory::create();

        // prefer SocketServer (reactphp/socket v1.9+) over legacy \React\Socket\Server
        $socket = class_exists('React\Socket\SocketServer') ? new SocketServer($address . ':' . $port, [], $loop) : new LegacySocketServer($address . ':' . $port, $loop);

        return new static($component, $socket, $loop);
    }

    /**
     * Run the application by entering the event loop
     * @throws \RuntimeException If a loop was not previously specified
     */
    public function run() {
        if (null === $this->loop) {
            throw new \RuntimeException("A React Loop was not provided during instantiation");
        }

        // @codeCoverageIgnoreStart
        $this->loop->run();
        // @codeCoverageIgnoreEnd
    }

    /**
     * Triggered when a new connection is received from React
     * @param \React\Socket\ConnectionInterface $conn
     */
    public function handleConnect(SocketConnection $conn) {
        // assign dynamic `$decor` property used by Ratchet without raising notice on PHP 8.2+
        // need this hack because we can't use `#[\AllowDynamicProperties]` on vendor code
        set_error_handler(function () { }, E_DEPRECATED);
        $conn->decor = new IoConnection($conn);
        restore_error_handler();

View on GitHub (pinned to e621c6c40b)