Debug
Inspect and modify function constants, prototypes, upvalues and stack values.
- debug.getregistry
- debug.getmetatable
- debug.setmetatable
- debug.getconstant
- debug.getconstants
- debug.setconstant
- debug.getupvalue
- debug.getupvalues
- debug.setupvalue
- debug.getproto
- debug.getprotos
- debug.getstack
- debug.setstack
- debug.getinfo
- debug.setinfo
- debug.getcallstack
- debug.isvalidlevel
- getcurrentline
- Native runtime debug functions
- debug.info
- debug.traceback
- error
The module extends debug with prototype, closure and frame readers. Indices for constants, child prototypes, upvalues and stack slots are 1-based. Stack levels refer to frames, not lexical local variable names. Nil values create holes in snapshot tables; use pairs when inspecting them.
Prototype readers accept a Luau function or a numeric stack level resolving to a Luau frame. C targets and unavailable frames raise errors. debug.getinfo also understands the module visible-stack mapping and original-thread context. The native runtime debug table is merged afterward, retaining client-provided functions such as debug.info and debug.traceback.
debug.getregistry
debug.getregistry(): tableReturns the calling VM registry table.
Returns
tableSame table as getreg().
Example
debug.getmetatable
debug.getmetatable(value: any): table?Returns the actual metatable, ignoring its __metatable visibility field.
Parameters
valueany- Value whose actual metatable is requested.
Returns
table?Raw metatable or nil.
Example
debug.setmetatable
debug.setmetatable(value: any, metatable: table?): table?Calls the native metatable setter directly. Unlike setrawmetatable, it does not temporarily clear a table readonly flag. With the normal two-argument call, it returns the supplied metatable, not the original value or a success boolean.
Parameters
valueany- Value to update.
metatabletable?- New table or nil.
Returns
table?Supplied metatable for a two-argument call.
Example
debug.getconstant
debug.getconstant(target: function | number, index: number): anyReads one raw constant-pool position. Function/table constants return nil. Invalid indices raise an error; this API has no compact-index argument.
Also available as getconstant.
Parameters
targetfunction | number- Luau function or stack level.
indexnumber- Positive raw constant index.
Returns
anyConstant value, or nil for a hidden/non-value position.
Example
debug.getconstants
debug.getconstants(target: function | number, pseudoIndices: boolean? = false): {any}Returns the constant pool. By default numeric keys retain raw positions and unsupported function/table entries become holes. With pseudoIndices true, those entries are skipped and the visible positions are compacted.
Also available as getconstants.
Parameters
targetfunction | number- Luau function or stack level.
pseudoIndicesboolean?- Optional.Compact past function/table constant positions. Default
false.
Returns
{any}Constant snapshot keyed by raw or compacted positions.
Example
debug.setconstant
debug.setconstant(target: function | number, index: number, value: any, pseudoIndices: boolean? = false): ()Replaces a constant while preserving its original TValue type. Supports nil, boolean, number, vector and string values; unsupported constants, mismatched types and invalid positions raise errors.
Also available as setconstant.
Parameters
targetfunction | number- Luau function or stack level.
indexnumber- Positive constant position.
valueany- Same-type replacement constant.
pseudoIndicesboolean?- Optional.Interpret index using the compact visible pool. Default
false.
Returns
()No values.
Example
debug.getupvalue
debug.getupvalue(target: function | number, index: number): anyReads one upvalue through the VM API. A direct function may be C or Luau. Missing/invalid upvalues raise errors; the result is the value only, not a name/value pair.
Also available as getupvalue.
Parameters
targetfunction | number- Function or nonnegative stack level.
indexnumber- Positive upvalue index.
Returns
anySelected upvalue value.
Example
debug.getupvalues
debug.getupvalues(target: function | number): {any}Reads all upvalues of a Luau closure, resolving open and closed captured cells. C functions raise Unsupported function.
Also available as getupvalues.
Parameters
targetfunction | number- Luau function or nonnegative stack level.
Returns
{any}Snapshot indexed by upvalue position; nil entries become holes.
Example
debug.setupvalue
debug.setupvalue(target: function | number, index: number, value: any): ()Writes one Luau closure upvalue through the native setter. C functions and invalid indices raise errors.
Also available as setupvalue.
Parameters
targetfunction | number- Luau function or nonnegative stack level.
indexnumber- Positive upvalue index.
valueany- Replacement value, including nil.
Returns
()No values.
Example
debug.getproto
debug.getproto(target: function | number, index: number, active: boolean? = false): function | {function}Reads one direct child prototype. The default result is an inspection closure constructed from a cloned prototype with a return-only body; it is not the original child executable body.
With active true, scans GC for existing live Luau closures using the exact child prototype and returns an array of those closures.
Also available as getproto.
Parameters
targetfunction | number- Luau parent closure or stack level.
indexnumber- Positive direct-child prototype position.
activeboolean?- Optional.Return live existing child closures instead of an inspection closure. Default
false.
Returns
function | {function}Inspection closure, or matching active closure array.
Example
debug.getprotos
debug.getprotos(target: function | number): {function}Builds inspection closures for each direct child prototype. Their cloned bodies return immediately; use getproto(target, index, true) when actual live executable child closures are needed.
Also available as getprotos.
Parameters
targetfunction | number- Luau parent closure or stack level.
Returns
{function}One inspection closure per direct child prototype.
Example
debug.getstack
debug.getstack(level: number, index: number? = nil): any | {any}Reads a raw register slot from a live Luau frame, or returns all frame slots when index is omitted. Non-dead values are copied; a dead collectible slot becomes nil. C frames and invalid levels/positions raise errors.
Also available as getstack.
Parameters
levelnumber- Nonnegative stack level resolving to a live Luau frame.
indexnumber?- Optional.Optional positive register-slot index. Default
nil.
Returns
any | {any}One register value or snapshot of all allocated frame slots.
Example
debug.setstack
debug.setstack(level: number, index: number, value: any? = nil): ()Writes a raw register slot in a live Luau frame. Omitted/nil value clears that slot. Slots are VM registers, not stable source-local names; invalid frames and positions raise errors.
Also available as setstack.
Parameters
levelnumber- Nonnegative live Luau frame level.
indexnumber- Positive register-slot index.
valueany?- Optional.Replacement slot value. Default
nil.
Returns
()No values.
Example
debug.getinfo
debug.getinfo(target: function | number, options: string? = "sluanf"): tableBuilds an information table for a function or positive visible stack level. Requested fields are selected by the option letters below. Missing stack levels raise an error.
Also available as getinfo.
Parameters
targetfunction | number- Function object or positive visible stack level.
optionsstring?- Optional.Requested option characters. Default
"sluanf".
Returns
tableOnly the requested information fields.
Example
debug.setinfo
debug.setinfo(target: function | number, information: table): ()Records optional debug-display overrides for name, source, short_src and currentline. Omitted fields remain unset in the replacement override record. It does not rewrite compiled code or line tables.
Parameters
targetfunction | number- Function or nonnegative stack level resolving to Luau.
informationtable- Optional name/source/short_src strings and currentline number.
Returns
()No values.
Example
debug.getcallstack
debug.getcallstack(thread: thread? = nil): {table}Collects frame entries for the current/original observed thread, or an explicitly supplied thread. Each entry contains func, name and source; Luau entries also contain currentline.
Also available as getcallstack.
Parameters
threadthread?- Optional.Optional explicit thread to inspect. Default
nil.
Returns
{table}Innermost-first frame entries; explicitly inspected foreign threads include level 0.
Example
debug.isvalidlevel
debug.isvalidlevel(level: number, thread: thread? = nil): booleanChecks for a function at a positive stack level. Nonpositive levels return false. An explicitly inspected finished or errored coroutine also returns false; noninteger levels raise an argument error.
Also available as isvalidlevel, validlevel and debug.validlevel.
Parameters
levelnumber- Integer stack level.
threadthread?- Optional.Thread to inspect; nil selects caller. Default
nil.
Returns
booleanWhether the frame currently resolves to a function.
Example
getcurrentline
getcurrentline(level: number? = 1): numberReturns the current source line of a positive stack level. Missing frames or frames without line information raise an error.
Also available as debug.getcurrentline.
Parameters
levelnumber?- Optional.Positive stack level. Default
1.
Returns
numberSource line number.
Example
Native runtime debug functions
The module copies the main runtime debug table into its extended table. These built-in names are supplied by the runtime rather than registered as aliases of the module getinfo function; additional client-specific fields are retained as provided by that runtime.
debug.info
debug.info([thread: thread,] target: function | number, options: string): ...anyReturns positional information in option-string order. s, l, n, and f select source, line, name and function; a returns parameter count followed by a boolean vararg flag. Duplicate/unknown option characters raise an error.
Parameters
threadthread?- Optional.Optional leading thread for stack inspection. Default
nil. targetfunction | number- Function object or stack level.
optionsstring- Requested option sequence.
Returns
...anyRequested positional results; an unavailable stack frame returns no values.
Example
debug.traceback
debug.traceback([thread: thread,] message: string? = nil, level: number? = 1): stringFormats a runtime stack traceback, optionally prepending a message. The default start level is 1 for the current thread and 0 when inspecting another thread. Negative levels raise an error.
Parameters
threadthread?- Optional.Optional leading thread to inspect. Default
nil. messagestring?- Optional.Optional message prefix. Default
nil. levelnumber?- Optional.First nonnegative stack level; defaults to 0 for another thread. Default
1.
Returns
stringFormatted stack trace.
Example
error
error(value: any, level: number? = 1): neverRaises the supplied error value. For string errors with a positive level, the module remaps the location through visible frames so hidden forwarding frames do not shift the reported caller. Nonstring values and level 0 retain the native behavior.
Parameters
valueany- Error object or message.
levelnumber?- Optional.Location-reporting level; 0 omits the source location. Default
1.
Returns
neverThe call raises an error and does not return normally.
Example
Written for Lynx 0.0.0
Something unclear? Tell us on Discord