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
- Send WAMP messages as JSON arrays with the message type as element 0, e.g. [5, "http://example.com/topic"], not JSON objects.
- 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.
- Log the raw incoming $msg before decoding to see exactly what the client sent, and fix the encoder on the client side.
- 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
- Always send WAMP frames as JSON arrays: [type, topic, ...], never JSON objects.
- Pin the client library to a WAMP v1-compatible version matching Ratchet.
- Add a pre-send serializer test asserting decoded frames are sequential arrays.
- Close connections on any WAMP protocol exception so a bad client cannot keep sending.
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
- Invalid Topic, must be a string
- Invalid WAMP message type
- Maximum buffer size of
- $request can not be null
- Expected instance of…
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)