@eryx/debugger Module

Debug Luau programs from Luau code.

The debugger library runs a target program under debugger control and exposes the primitives needed by debuggers and editor adapters: session lifecycle, event delivery, source lookup, breakpoints, coroutine threads, stack frames, scopes, variable inspection, expression evaluation, variable assignment, exception details, output events, stepping, pausing, termination, and VM bytecode disassembly.

Use debugger.open() to create a Session. Configure the session before starting it, usually by setting breakpoints, then call Session:start() and read events with Session:wait(). When a stopped event is received, use the event's threadId with Session:frames(), then inspect frames with Session:scopes(), Session:inspect(), Session:evaluate(), or Session:setVariable(). Resume execution with Session:resume() or Session:step().

Luau coroutines are reported as debugger threads. Thread identifiers are stable for known coroutines within a session. Frame, scope, evaluation, and mutation operations are guaranteed for the current stopped thread; other known threads may be listed even when they do not have inspectable frames.

Summary

Classes

Session:start()()
Session:resume(threadId: ThreadId?)()
Session:pause(threadId: ThreadId?)()
Session:step(mode: StepMode, threadId: ThreadId?)()
Session:close(terminateDebuggee: boolean?)()
Session:readSource(source: (SourceId | Source)?)string
Session:setBreakpoints(source: SourceId | Source, breakpoints: { BreakpointSpec }){ Breakpoint }
Session:frames(threadId: ThreadId?, start: number?, count: number?){ frames: { Frame }, total: number? }
Session:scopes(frame: FrameId){ Scope }
Session:evaluate(expression: string, options: EvaluateOptions?)EvaluateResult
Session:setVariable(ref: ValueRef, name: string, expression: string, options: SetVariableOptions?)EvaluateResult

Functions

API Reference

Classes

Session

Debugger session returned by debugger.open().

Properties

Session:start

Starts the debuggee once breakpoints and listeners are configured.

Session:start()()

Session:wait

⚠ Yields

Waits for and returns the next debugger event.

Session:wait()SessionEvent?

Returns

Next debugger event, or nil when the session has ended and no events remain.

Session:state

Returns the current coarse session state.

Session:state()SessionState

Returns

Current session state.

Session:threads

Returns known Luau coroutine threads in the debuggee.

Session:threads(){ Thread }

Returns

{ Thread }

Known threads for the session.

Session:resume

Resumes execution for a thread or the whole debuggee.

Session:resume(threadId: ThreadId?)()

Parameters

threadId: ThreadId?

Thread to resume. Omit to resume the current paused debuggee.

Session:pause

Requests that execution pause at the next source-backed interrupt point.

Session:pause(threadId: ThreadId?)()

Parameters

threadId: ThreadId?

Thread to pause. Omit to pause the next eligible running thread.

Session:step

Steps a paused thread using the requested mode.

Session:step(mode: StepMode, threadId: ThreadId?)()

Parameters

mode: StepMode

Step operation to perform.

threadId: ThreadId?

Paused thread to step. Omit to step the current paused thread.

Session:terminate

Requests debugger termination and debuggee shutdown.

Session:terminate()()

Session:close

Closes the session, optionally terminating the debuggee first.

Session:close(terminateDebuggee: boolean?)()

Parameters

terminateDebuggee: boolean?

Whether to terminate a live debuggee before closing. Defaults to true.

Session:sources

Lists sources currently known to the debugger.

Session:sources(){ Source }

Returns

{ Source }

Known sources.

Session:readSource

Reads source text for a known source.

Session:readSource(source: (SourceId | Source)?)string

Parameters

source: (SourceId | Source)?

Source identifier or descriptor. Omit to read the program source.

Returns

string

Source text, or an empty string when the source cannot be read.

Session:setBreakpoints

Replaces source breakpoints for a source.

Session:setBreakpoints(source: SourceId | Source, breakpoints: { BreakpointSpec }){ Breakpoint }

Parameters

source: SourceId | Source

Source identifier or descriptor receiving the new breakpoint set.

breakpoints: { BreakpointSpec }

Breakpoints to set for the source.

Returns

Resolved breakpoint records.

Session:clearBreakpoints

Clears source breakpoints for one source, or all user breakpoints when omitted.

Session:clearBreakpoints(source: SourceId | Source?)()

Parameters

source: SourceId | Source?

Source identifier or descriptor to clear. Omit to clear all user breakpoints.

Session:frames

Returns stack frames for a thread.

Session:frames(threadId: ThreadId?, start: number?, count: number?){ frames: { Frame }, total: number? }

Parameters

threadId: ThreadId?

Thread whose frames should be returned. Omit to use the current stopped thread.

start: number?

Zero-based frame offset.

count: number?

Maximum number of frames to return.

Returns

{ frames: { Frame }, total: number? }

Frame page and total frame count.

Session:scopes

Returns the visible scopes for a frame.

Session:scopes(frame: FrameId){ Scope }

Parameters

frame: FrameId

Frame identifier captured during the current pause.

Returns

{ Scope }

Scopes visible from the frame.

Session:inspect

Expands values referenced by a scope or prior inspection result.

Session:inspect(query: InspectQuery){ Value }

Parameters

Value expansion request.

Returns

{ Value }

Expanded child values.

Session:evaluate

Evaluates code in the context of a paused frame.

Session:evaluate(expression: string, options: EvaluateOptions?)EvaluateResult

Parameters

expression: string

Luau expression or, when allowed, statement chunk to evaluate.

options: EvaluateOptions?

Evaluation options.

Returns

Evaluation result containing either a value or an error.

Session:setVariable

Assigns a variable or table child referenced by a scope or inspection result.

Session:setVariable(ref: ValueRef, name: string, expression: string, options: SetVariableOptions?)EvaluateResult

Parameters

Scope or value reference containing the variable.

name: string

Variable name or table key to assign.

expression: string

Luau expression used to produce the assigned value.

Assignment options.

Returns

Assignment result containing either the new value or an error.

Session:disassemble

Returns a VM bytecode disassembly for a source or paused frame.

Session:disassemble(options: (SourceId | Source | DisassembleOptions)?)string

Parameters

Source, source descriptor, or disassembly options. Omit to disassemble the program source.

Returns

string

Human-readable bytecode listing.

Session:exception

Returns the currently captured exception, if any.

Session:exception(threadId: ThreadId?)Exception?

Parameters

threadId: ThreadId?

Thread whose exception should be queried. Omit to query the current stopped thread.

Returns

Captured exception details, or nil when no exception is available.

Functions

debugger.open

Opens a debugger session for a Luau program.

The debuggee is not started until Session:start() is called. Configure breakpoints and event consumers before starting the session.

debugger.open(options: SessionOptions)Session

Parameters

Session options. options.program is required.

Returns

New debugger session.

debugger.breakpoint

Breaks into the active debugger from inside the debuggee.

Call this from debuggee code to emit a stopped event with reason "manual". If the current runtime is not running under debugger.open(), the call has no effect.

debugger.breakpoint()()

Types

ThreadId

Identifies a Luau coroutine thread within a session.

type ThreadId = number
Implements: number

FrameId

Identifies a stack frame captured during the current pause.

type FrameId = number
Implements: number

BreakpointId

Identifies a source breakpoint within a session.

type BreakpointId = number
Implements: number

ValueRef

Identifies an expandable scope or value.

type ValueRef = number
Implements: number

SessionState

Session lifecycle state.

type SessionState = "starting" | "idle" | "running" | "paused" | "terminated"

ThreadState

Debugger-visible state for a known coroutine thread.

type ThreadState = "running" | "paused" | "terminated"

StepMode

Step operation accepted by Session:step().

type StepMode = "in" | "over" | "out"

StopReason

Stop reason reported by a stopped event.

type StopReason = "entry" | "breakpoint" | "step" | "pause" | "exception" | "manual"

EvaluateContext

Evaluation context supplied by debugger clients.

type EvaluateContext = "watch" | "repl" | "hover" | "clipboard" | "variables" | "condition" | "logpoint"

OutputStream

Output stream category.

type OutputStream = "stdout" | "stderr" | "console" | "telemetry"

ValueKind

Category of an expandable debugger value.

type ValueKind = "value" | "locals" | "registers"

ValueFilter

Child filter for Session:inspect().

type ValueFilter = "all" | "named" | "indexed"

SourceId

Stable source identifier.

type SourceId = string
Implements: string

Source

Source file or chunk known to the session.

type Source = { id: SourceId, name: string?, path: string?, kind: string? }

Stable debugger-facing source identifier.

name: string?

Human-friendly label, usually the source basename.

path: string?

Concrete filesystem path when the source is file-backed.

kind: string?

Optional source category such as "file" or "embedded".

Thread

Luau coroutine thread known to the session.

type Thread = { id: ThreadId, name: string, state: ThreadState, stopReason: StopReason? }

Stable thread identifier within the session.

name: string

Human-friendly thread name.

Current debugger-visible thread state.

stopReason: StopReason?

Reason this thread is paused, when state is "paused".

BreakpointSpec

Breakpoint request passed to Session:setBreakpoints().

type BreakpointSpec = { line: number, column: number?, condition: string?, hitCondition: string?, logMessage: string? }
line: number

Requested one-based source line.

column: number?

Optional one-based source column.

condition: string?

Expression that must evaluate truthy before the breakpoint stops.

hitCondition: string?

Hit-count expression such as "3", ">= 5", or "% 2".

logMessage: string?

Logpoint message. Braced expressions are evaluated at the hit location.

Breakpoint

Breakpoint returned by Session:setBreakpoints().

type Breakpoint = { id: BreakpointId?, source: Source, line: number, column: number?, verified: boolean, message: string? }

Stable breakpoint identifier when the breakpoint was accepted.

source: Source

Source where the breakpoint was requested or resolved.

line: number

One-based resolved or requested source line.

column: number?

One-based resolved or requested source column.

verified: boolean

Whether the debugger could bind this breakpoint to loaded code.

message: string?

Human-readable explanation when the breakpoint is pending or rejected.

Frame

Stack frame returned by Session:frames().

type Frame = { id: FrameId, threadId: ThreadId?, name: string, source: Source?, line: number, column: number, pc: number?, instruction: string? }

Stable frame identifier for the current pause.

threadId: ThreadId?

Thread that owns this frame.

name: string

Function or chunk name for display.

source: Source?

Source location for this frame, when available.

line: number

One-based source line.

column: number

One-based source column.

pc: number?

VM instruction program counter, when available.

instruction: string?

Debugger instruction identifier for disassembly-oriented clients.

Scope

Variable scope returned by Session:scopes().

type Scope = { name: string, kind: ValueKind?, ref: ValueRef, expensive: boolean, namedCount: number?, indexedCount: number?, source: Source?, line: number?, column: number? }
name: string

Scope display name, such as "Locals" or "Registers".

kind: ValueKind?

Kind of values exposed by this scope.

Value reference used to expand the scope with inspect.

expensive: boolean

Whether expanding the scope may be relatively expensive.

namedCount: number?

Number of named children when known.

indexedCount: number?

Number of array-like children when known.

source: Source?

Source associated with this scope, when available.

line: number?

One-based source line associated with this scope, when available.

column: number?

One-based source column associated with this scope, when available.

Value

Value returned by Session:inspect(), Session:evaluate(), or Session:setVariable().

type Value = { name: string, summary: string, type: string?, ref: ValueRef, kind: ValueKind?, namedCount: number?, indexedCount: number?, evaluateName: string? }
name: string

Display name for the value.

summary: string

Human-readable value summary.

type: string?

Luau type name or debugger-specific type label.

Value reference for expansion, or 0 when the value has no children.

kind: ValueKind?

Kind of value reference.

namedCount: number?

Number of named children when known.

indexedCount: number?

Number of array-like children when known.

evaluateName: string?

Expression that can be evaluated to retrieve this value again.

InspectQuery

Expansion request for Session:inspect().

type InspectQuery = { ref: ValueRef, start: number?, count: number?, filter: ValueFilter?, hex: boolean? }

Scope or value reference to expand.

start: number?

Zero-based child offset.

count: number?

Maximum number of children to return.

filter: ValueFilter?

Child category to return.

hex: boolean?

Whether numeric summaries should prefer hexadecimal formatting.

EvaluateOptions

Options for Session:evaluate().

type EvaluateOptions = { frame: FrameId?, context: EvaluateContext?, hex: boolean?, allowStatements: boolean? }
frame: FrameId?

Frame used as the lexical evaluation context.

context: EvaluateContext?

UI or protocol context for the evaluation request.

hex: boolean?

Whether numeric summaries should prefer hexadecimal formatting.

allowStatements: boolean?

Whether statement chunks may run when expression evaluation fails.

SetVariableOptions

Options for Session:setVariable().

type SetVariableOptions = { frame: FrameId?, hex: boolean? }
frame: FrameId?

Frame used as the lexical evaluation context for the assigned expression.

hex: boolean?

Whether numeric summaries should prefer hexadecimal formatting.

DisassembleOptions

Options for Session:disassemble().

type DisassembleOptions = { source: (SourceId | Source)?, frame: FrameId?, showLocals: boolean?, showRemarks: boolean?, showTypes: boolean? }
source: (SourceId | Source)?

Source to disassemble. Defaults to the frame source or program source.

frame: FrameId?

Frame whose source should be disassembled when source is omitted.

showLocals: boolean?

Whether local-variable debug information should be included.

showRemarks: boolean?

Whether compiler remarks should be included.

showTypes: boolean?

Whether type debug information should be included.

EvaluateResult

Result returned by Session:evaluate() and Session:setVariable().

type EvaluateResult = { ok: true, value: Value } | { ok: false, error: { message: string, type: string? } }

Exception

Exception details captured for an exception stop.

type Exception = { id: string, message: string?, typeName: string?, description: string?, stackTrace: string?, source: Source?, line: number?, column: number? }
id: string

Exception identifier or category.

message: string?

Primary exception message.

typeName: string?

Luau exception type name when available.

description: string?

Human-readable exception description.

stackTrace: string?

Formatted stack trace.

source: Source?

Source associated with the selected exception location.

line: number?

One-based source line associated with the exception.

column: number?

One-based source column associated with the exception.

SessionEventState

Event emitted when the session state changes.

type SessionEventState = { kind: "state", state: SessionState, threadId: ThreadId? }
kind: "state"

Event discriminator.

New session state.

threadId: ThreadId?

Thread related to the state change, when available.

SessionEventStopped

Event emitted when the debuggee stops.

type SessionEventStopped = { kind: "stopped", threadId: ThreadId, reason: StopReason, description: string?, text: string?, breakpoints: { BreakpointId }?, source: Source?, line: number?, column: number? }
kind: "stopped"

Event discriminator.

threadId: ThreadId

Thread that stopped.

reason: StopReason

Reason execution stopped.

description: string?

Human-readable stop description.

text: string?

Additional stop text, such as an exception message.

breakpoints: { BreakpointId }?

Breakpoints hit by this stop.

source: Source?

Source location for the stop.

line: number?

One-based source line for the stop.

column: number?

One-based source column for the stop.

SessionEventOutput

Event emitted for debuggee or debugger output.

type SessionEventOutput = { kind: "output", stream: OutputStream, text: string, source: Source?, line: number?, column: number? }
kind: "output"

Event discriminator.

stream: OutputStream

Output stream category.

text: string

Output text.

source: Source?

Source associated with the output, when available.

line: number?

One-based source line associated with the output.

column: number?

One-based source column associated with the output.

SessionEventSource

Event emitted when a source is added, changed, or removed.

type SessionEventSource = { kind: "source-added" | "source-changed" | "source-removed", source: Source }
kind: "source-added" | "source-changed" | "source-removed"

Event discriminator.

source: Source

Source that changed.

SessionEventTerminated

Event emitted when the debuggee terminates.

type SessionEventTerminated = { kind: "terminated", exitCode: number? }
kind: "terminated"

Event discriminator.

exitCode: number?

Process-style exit code when available.

SessionEvent

Event returned by Session:wait().

SessionOptions

Options for debugger.open().

type SessionOptions = { program: string, args: { string }?, stopOnEntry: boolean?, nativeCodegen: boolean?, optimisationLevel: number? }
program: string

Entry file for the debuggee.

args: { string }?

Command-line arguments visible to the debuggee.

stopOnEntry: boolean?

Whether to pause before the first line executes.

nativeCodegen: boolean?

Whether native codegen should be enabled for the debuggee.

optimisationLevel: number?

Luau optimization level used to compile the debuggee.