VINDICTA
Metatables · Function
Bunni.fun
ChocoSploit
Cryptic
Potassium
Seliware
SirHurt
Solara
Velocity
Volcano
Volt
Wave
Xeno

isreadonly

Returns whether a table is frozen (read-only).

function isreadonly(t: table): boolean

Synopsis

How it works

Checks the readonly flag on the table header. In Luau, tables have an internal boolean flag that prevents writes when set. This flag is separate from metatablesMetatableA table attached to another table (or userdata) that defines operator overloading via metamethods (__index, __newindex, __call, etc.). Roblox Instances use shared read-only metatables for method dispatch. — the __newindex metamethodMetamethodA function in a metatable that overrides default behavior for operations like indexing (__index), assignment (__newindex), calling (__call), comparison (__eq), and arithmetic (__add, __mul, etc.). is never consulted because the VM rejects the write at the table-access level before metamethod dispatch.

VM internals

The flag lives in the Table struct header:
typedef struct Table {
  GCObject header;
  uint8_t tmcache;   // tag method cache
  uint8_t readonly;  // ← this flag (0 = mutable, 1 = frozen)
  uint8_t safeenv;
  // ...
} Table;
When readonly == 1, the VM’s SETTABLEKS, SETTABLEN, and SETTABLE opcodes check this field first and throw "Attempt to modify a readonly table" before any metamethodMetamethodA function in a metatable that overrides default behavior for operations like indexing (__index), assignment (__newindex), calling (__call), comparison (__eq), and arithmetic (__add, __mul, etc.). lookup. The freeze check happens at the C level before __newindex is even considered. table.freeze() and setreadonly(t, true) both set this byte.

Usage

Check table mutability
local t = table.freeze({})
print(isreadonly(t)) "cc">--> true

Parameters

t table
The table to check.

Returns

boolean true if the table is frozen.