Errors

A closed vocabulary defined in @open-rgs/contract. The orchestrator surfaces these codes on the wire as ERROR frames (0xff) with shape { code, message }.

Codes

CodeFires when
INVALID_FORMATframe wasn't a binary message (e.g. a text or empty frame)
DECODE_ERRORmsgpack payload couldn't be decoded, or an unknown message code
MISSING_SESSIONrequest needs sid but none was supplied or attached
SESSION_NOT_FOUNDplatform openSession rejected the id
SESSION_INVALIDsession exists but is closed / blocked / expired
INSUFFICIENT_BALANCEpre-flight check failed for the requested bet
INVALID_BETbetIndex out of range, or bet 0 or less
INVALID_MODEmode id unknown, internal, or wrong kind
INVALID_ACTIONSTEP action.type doesn't match awaiting.type
INVALID_ROUNDCLOSE on a non-terminal round, or STEP on a terminal one
ROUND_ALREADY_OPENOPEN issued while a round is already in flight
NO_ROUND_OPENSTEP / CLOSE issued with no round in flight
PLATFORM_UNAVAILABLEplatform adapter isHealthy === false
MATH_TIMEOUTmath exceeded its per-call execution budget and was aborted
INIT_FAILEDuncaught failure inside init
SPIN_FAILEDuncaught failure inside spin
OPEN_FAILEDuncaught failure inside openRound
STEP_FAILEDuncaught failure inside stepRound
CLOSE_FAILEDuncaught failure inside closeRound
INTERNAL_ERRORcatch-all; check /admin/logs

Throwing from adapters & math

import { RGSError } from "@open-rgs/contract";

async settleSimple(req) {
  if (response.status === 402) {
    throw new RGSError("INSUFFICIENT_BALANCE", "wallet declined");
  }
  // ...
}

Throw RGSError from adapter methods to surface a specific code; the orchestrator forwards it to the client as-is. Plain Errors become INTERNAL_ERROR. From Lua math, raise error("INVALID_ACTION: ...") - messages starting with a known code map to that code; everything else becomes *_FAILED for the active call.