ratchetphp/Ratchet · error · Exception

Invalid WAMP message format

Error message

Invalid WAMP message format

What it means

Ratchet\Wamp\ServerProtocol::onMessage throws "Invalid WAMP message format" when a decoded WebSocket frame is not a JSON array of consecutively-indexed elements. WAMP messages must be JSON arrays (e.g. [5, "topic"]); an object keyed with strings or a sparse array fails the `$json === array_values($json)` check. The library throws because it cannot route a non-array payload through its `switch ($json[0])` message-type dispatch.

Solutions

  1. Send WAMP messages as JSON arrays with the message type as element 0, e.g. [5, "http://example.com/topic"], not JSON objects.
  2. Check the client library version: Ratchet implements legacy WAMP v1; ensure the client (autobahn-js v0.x era, not newer Crossbar-oriented stacks) speaks the same protocol.
  3. Log the raw incoming $msg before decoding to see exactly what the client sent, and fix the encoder on the client side.
  4. Catch \Ratchet\Wamp\Exception in the onError handler of your decorating component and close or ignore misbehaving connections.

Example fix

// before (client, JavaScript)
ws.send(JSON.stringify({ type: 5, topic: 'kittens' }));
// after
ws.send(JSON.stringify([5, 'kittens']));
Defensive patterns

Strategy: validation

Validate before calling

$decoded = json_decode($msg, true);
if (!is_array($decoded) || $decoded !== array_values($decoded)) {
    // reject before sending: WAMP v1 requires a numerically-indexed JSON array
}

Type guard

function isWampArrayMessage($msg): bool {
    $d = json_decode($msg, true);
    return is_array($d) && $d !== [] && $d === array_values($d);
}

Try / catch

try {
    $server->onMessage($conn, $msg);
} catch (\Ratchet\Wamp\Exception $e) {
    $conn->close(); // malformed frame: drop the connection
}

Prevention

When it happens

Trigger: A client sends valid JSON that decodes to an associative object (e.g. `{"type":5}`) instead of a numbered array, or sends a JSON array with non-sequential keys impossible in strict JSON but possible when decoding objects cast to arrays, or sends a JSON scalar/null/number/string like `"hello"` or `42`, all of which fail `is_array` or the array_values comparison.

Common situations: Custom or hand-rolled client code that emits WAMP messages as JSON objects instead of arrays; a JS client doing JSON.stringify({topic: x}) instead of JSON.stringify([5, topic]); a WAMP v2/RAWS client speaking a newer protocol flavor than Ratchet's legacy WAMP v1 expects; a bot or fuzzer probing the socket.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/Ratchet/Wamp/ServerProtocol.php:93

        $this->connections->offsetSet($conn, $decor);

        $this->_decorating->onOpen($decor);
    }

    /**
     * {@inheritdoc}
     * @throws \Ratchet\Wamp\Exception
     * @throws \Ratchet\Wamp\JsonException
     */
    public function onMessage(ConnectionInterface $from, $msg) {
        $from = $this->connections[$from];

        if (null === ($json = @json_decode($msg, true))) {
            throw new JsonException;
        }

        if (!is_array($json) || $json !== array_values($json)) {
            throw new Exception("Invalid WAMP message format");
        }

        if (isset($json[1]) && !(is_string($json[1]) || is_numeric($json[1]))) {
            throw new Exception('Invalid Topic, must be a string');
        }

        switch ($json[0]) {
            case static::MSG_PREFIX:
                $from->WAMP->prefixes[$json[1]] = $json[2];
            break;

            case static::MSG_CALL:
                array_shift($json);
                $callID  = array_shift($json);
                $procURI = array_shift($json);

                if (count($json) == 1 && is_array($json[0])) {
                    $json = $json[0];

View on GitHub (pinned to e621c6c40b)