TracciattoThis extension provides Ruby debugging using the debug library. It supports the official
Table of ContentsGetting StartedTracciatto uses rdbg to support the two main debugging workflows:
Launching a debug sessionOption 1: Launch configuration
Option 2: Debug command
This command uses an internal debug configuration, so Attaching to a running processTo attach to a running Ruby process, you must have started it with Example: Start a script with the debugger open on a given port
Example: Start a script with the debugger open on a given socket
Alternatively, you can modify your code to launch the debugger explicitly when needed. Refer to the debug library documentation for details. Example: Start the debugger programmatically
In all cases, the debug library will print a Once the port or socket are setup, you can use one of the following options to attach to it. Option 1: Launch configuration
Option 2: Attach-to command
ConfigurationTracciatto supports the following user and workspace settings:
Debug Protocol OverridesThe following settings customize debugger behavior by modifying specific Debug Adapter Protocol messages. They affect UI surfaces that render debugger results like the Variables and Watches views, or the Debug console itself.
These changes are protocol‑compliant, but they modify low‑level DAP behavior and can be disabled if they cause issues.
|
| Setting | Description | Default |
|---|---|---|
tracciatto.rubyEnvironmentManager |
Select a version manager: none, asdf, rbenv, rvm, or use custom to provide your own command via tracciatto.customRubyEnvironmentCommand. See Managers for details. |
none |
tracciatto.customRubyEnvironmentCommand |
A command-line used to retrieve the Ruby environment. See Custom Managers for details. | |
tracciatto.customRubyEnvironmentCommandOutputFormat |
Specifies the output format of the command defined by the tracciatto.customRubyEnvironmentCommand setting. |
json |
Managers
Managers are used to discover the base environment used to launch a debug program. Any environment values defined in your debug configuration are applied on top of it.
The environment is isolated per workspace folder and per debug session, making it compatible with multi-root workspaces.
The environment is calculated once and cached, with invalidation rules. If the environment seems incorrect, reload the current window.
The following managers are supported:
none: Tracciatto does not use any version manager. Ruby is launched exactly as configured in your debug configuration or as found on your system PATH.asdf: Useasdfto resolve the Ruby version and environment.rbenv: Userbenvto resolve the Ruby version and environment.rvm: Use RVM to resolve the Ruby version and environment.custom: See Custom Managers.
Custom Managers
The custom manager-type gives you full control over how Ruby is resolved.
It also allows supporting any future or niche manager without waiting for an extension update.
Once enabled, you must provide a command-line for the tracciatto.customRubyEnvironmentCommand setting.
This command must print the Ruby environment as either:
- JSON (
JSON.dump(ENV.to_h)), e.g.rbenv exec ruby -- -rjson -e 'print JSON.dump(ENV.to_h)'
or
- one
KEY=VALUEpair per line, e.g.rbenv exec ruby -e 'ENV.each { |k,v| puts "#{k}=#{v}" }'
Use the tracciatto.customRubyEnvironmentCommandOutputFormat setting to specify the format the command outputs.
The following table shows examples of how to configure common tools using custom (generated using Copilot; results may vary):
| Manager | Example | Notes |
|---|---|---|
| chruby | chruby-exec ruby -- ruby -rjson -e 'print JSON.dump(ENV.to_h)' |
Requires chruby-exec |
| devbox | devbox run -- ruby -rjson -e 'print JSON.dump(ENV.to_h)' |
Uses devbox's environment |
| direnv | direnv exec . ruby -rjson -e 'print JSON.dump(ENV.to_h)' |
Runs Ruby inside the direnv-managed environment |
| Docker | docker compose exec app ruby -rjson -e 'print JSON.dump(ENV.to_h)' |
For containerized Ruby apps |
| mise | mise exec ruby -- -rjson -e 'print JSON.dump(ENV.to_h)' |
Uses mise's environment |
| nix-shell | nix-shell --run "ruby -rjson -e 'print JSON.dump(ENV.to_h)'" |
Uses the project's nix shell |
| WSL | wsl ruby -rjson -e 'print JSON.dump(ENV.to_h)' |
Uses Ruby inside WSL |
Debug Configurations
This extension provides two debugger types for Ruby, both powered by the debug library:
tracciatto: a custom debug type designed to follow a schema closer to other VS Code debuggers, with additional quality‑of‑life features.rdbg: the official Ruby debugger type, supported directly by this extension for convenience and interoperability.
Both debugger types are fully usable, and you can choose whichever best fits your workflow.
tracciatto
The tracciatto debug type is implemented directly by this extension. It supports both launch and attach modes with the following properties:
Launch Properties
| Property | Description |
|---|---|
args |
Arguments passed to the Ruby program. |
cwd |
Working directory. |
env |
Environment variables passed to the Ruby program. |
localfs |
Passthrough option forwarded directly to rdbg for local filesystem access configuration. |
localfsMap |
Passthrough option forwarded directly to rdbg for mapping local filesystem paths. This is a comma-separated list of remote_dir:local_dir mappings, e.g. /remote/folder1:/local/folderA,/remote/folder2:/local/folderB. |
port |
[host:]port path to the rdbg DAP server. |
program |
Ruby file to debug (required). |
rdbgPath |
Optional absolute path to rdbg. |
runtimeExecutable |
Ruby command to run (ruby by default). |
skipPaths |
Paths to skip when stepping. |
socket |
Socket path to the rdbg DAP server. |
socketTimeoutMs |
Timeout in milliseconds for the rdbg socket to appear before failing. Set to 0 to fail immediately. |
Attach Properties
| Property | Description |
|---|---|
localfs |
Passthrough option forwarded directly to rdbg for local filesystem access configuration. |
localfsMap |
Passthrough option forwarded directly to rdbg for mapping local filesystem paths. This is a comma-separated list of remote_dir:local_dir mappings. e.g. /remote/folder1:/local/folderA,/remote/folder2:/local/folderB. |
port |
[host:]port path to the rdbg DAP server. |
rdbgPath |
Optional absolute path to rdbg. |
skipPaths |
Paths to skip when stepping. |
socket |
Socket path to the rdbg DAP server. |
socketTimeoutMs |
Timeout in milliseconds for the rdbg socket to appear before failing. Set to 0 to fail immediately. |
rdbg (vscode‑rdbg)
This extension supports the rdbg debug type, normally contributed by the vscode‑rdbg extension. Most configuration properties are supported, while unsupported ones are safely ignored. When a property is not directly supported, it is typically because an equivalent capability is already provided through a configuration setting.
Tracciatto automatically disables its rdbg debug-type support if the vscode‑rdbg extension is installed to prevent having both extensions attempting to claim the same debug type. This happens even if the vscode‑rdbg extension is disabled as VS Code does not provide a reliable way to determine another extension's activation state or distinguish between "disabled" and "not yet activated".
The tracciatto.forceEnableRdbgDebugType setting allows to force rdbg registration even when vscode‑rdbg is installed, as long as it is inactive at registration time. Note that whichever extension attempts registration second will fail, although Tracciatto handles this situation gracefully a log entry. This setting exists so users can experiment with Tracciatto by simply disabling vscode‑rdbg instead of having to uninstall it.
You must reload the window after installing, uninstalling, enabling, or disabling vscode‑rdbg as dbug-type registration only happens during extension activation. Check the logs to confirm which debug-types are active.
Launch Properties
| Property | Description |
|---|---|
args |
Arguments passed to the Ruby program. |
command |
Command name (ruby, rake, bin/rails, bundle exec ruby, etc). |
cwd |
Working directory. |
debugPort |
[host:]port endpoint or socket path to the rdbg DAP server. |
env |
Environment variables passed to the Ruby program. |
localfs |
Passthrough option forwarded directly to rdbg for local filesystem access configuration. |
localfsMap |
Passthrough option forwarded directly to rdbg for mapping local filesystem paths. This is a comma-separated list of remote_dir:local_dir mappings. e.g. /remote/folder1:/local/folderA,/remote/folder2:/local/folderB. |
rdbgPath |
Absolute path to rdbg. |
script |
Absolute path to a Ruby file (required). |
showProtocolLog |
Log DAP communication messages. Prefer tracciatto.logDapMessages setting. |
useBundler |
Use bundle exec to run Ruby program. Prefer tracciatto.preferBundler setting. |
Attach Properties
| Property | Description |
|---|---|
debugPort |
[host:]port endpoint or socket path to the rdbg DAP server. |
localfs |
Passthrough option forwarded directly to rdbg for local filesystem access configuration. |
localfsMap |
Passthrough option forwarded directly to rdbg for mapping local filesystem paths. This is a comma-separated list of remote_dir:local_dir mappings. e.g. /remote/folder1:/local/folderA,/remote/folder2:/local/folderB. |
rdbgPath |
Optional absolute path to rdbg. |
showProtocolLog |
Log DAP communication messages. Prefer tracciatto.logDapMessages setting. |
Commands
The following commands are intended for quick verification of standalone scripts, not as a replacement for a workspace launch configuration. Code is run using the tracciatto.runtimeExecutable setting value (defaults to ruby).
| Command | Description |
|---|---|
| Attach to… | Attach to a [host:]port endpoint or socket path, e.g. "1234", "localhost:5678", or "/tmp/socket". When exactly one workspace folder is open, it is used as a source of skip-paths. In multi‑root workspaces no folder is selected. The tracciatto.skipPathsFileName setting is always used as it is only defined in User settings. |
| Attach to Multiple… | Attach to a comma-separated list of [host:]port endpoints or socket paths, e.g. "1234, /tmp/socket, localhost:5678" For a single target, prefer Attach to…. This command otherwise follows the same execution behavior as Attach to…. |
| Debug Active Editor | Debugs the active Ruby editor. |
| Run Active Editor | Executes the active Ruby file. |
| Set Maximum Inspected Value Length | Sets the maximum length of inspected values for the current debug session only. This is useful when you temporarily need more (or less) detail in variable previews. To configure this permanently across all sessions, use the tracciatto.patchMaxInspectedValueLength setting. |
Breakpoints
The following breakpoint types are supported from UI:
Line Breakpoint: stops at a specific file/line.
- Set by clicking the editor gutter or pressing F9.
- Debug console:
break <file>:<line>
Conditional Line Breakpoint: stops only if an expression evaluates truthy.
- Set by right‑clicking a line breakpoint → Edit Breakpoint….
- Debug console:
break <file>:<line> if <expr>
Catch Breakpoint: stops when a specific exception class is raised.
- rdbg's native integration only exposes rescue any exception and rescue RuntimeError in the VS Code Breakpoints view.
- Tracciatto expands this via the Exception Filters view.
- Debug console:
catch <ExceptionClass>
The following breakpoint types depend on runtime entities (methods, objects, or expressions).
These breakpoints cannot be preset in the general case because the target entities do not exist until the Ruby VM loads the relevant code. They can only reliably be defined during an active debug session.
VS Code allows adding some of these using the Add Function Breakpoint command, but rdbg will silently fail to set them up at session startup unless the method/object already exists (e.g., when attaching to a long‑running process).
Method Breakpoint: stops when a method is called.
- Supported in VS Code as function breakpoints.
- Debug console:
break <Class>.<method>orbreak <Class>#<method>
Object Breakpoint: stops when a specific object is used as receiver/argument.
- No VS Code UI entry point.
- Debug console:
watch object <expr>
Watch Breakpoint: stops when the value of an expression changes.
- No VS Code UI entry point.
- Debug console:
watch <expr>
Temporary Breakpoint: stops once, then removes itself.
- No VS Code UI entry point.
- Debug console:
break <file>:<line> once
Tracepoint (line/call/exception/object): logs events without stopping.
- No VS Code UI entry point.
- Debug console:
trace <event>(e.g.,trace call,trace line)
Template Formats
Ruby template formats such as ERB, Haml, and Slim are not supported for stepping or breakpoints.
These files are compiled into temporary Ruby code at runtime, and the Ruby VM does not expose file/line information that rdbg can map back to the original template. As a result, breakpoints in template files will appear unverified and will not be hit.
Debugging is fully supported only for Ruby source files (.rb, .rake, etc.), or more specifically, for source files whose VS Code language is ruby. Alternatively, you can enable the Debug: Allow Breakpoints Everywhere setting.
To inspect template behavior, place breakpoints in controllers, helpers, or view objects instead.
Exception Filters
The Exception Filters view provides a convenient way to manage Ruby exceptions that should trigger a breakpoint in rdbg. It is similar to the catch command, but offers several advantages: filters are applied automatically at the start of every debugging session, can be toggled at any time, and allow you to maintain a project-specific list of exceptions.
Exceptions are organized into two groups:
- Built‑in Filters: Common Ruby exception classes provided by the extension. Built‑in filters cannot be edited or removed, but they can be enabled or disabled as needed.
LoadErroris enabled by default because unresolvedrequirestatements and other code-loading failures can cause the debug session to terminate immediately without stopping in the debugger.
- User Filters: Custom Ruby exception classes (for example,
NoMethodError,KeyError, orActiveRecord::RecordNotFound) defined for the current workspace.
Exception filters can be toggled at any time, and their state is saved across debugging sessions. Changes are either applied immediately to active debug sessions or automatically applied when the next debugging session starts.
Skip-Path Patterns
Rdbg supports skip‑paths glob patterns that tell the debugger which files it should not step into. This affects not only step-by-step debugging but also specific frames the debugger shows as part of the current call stack. For complex projects, this is invaluable as there might be significant portions of the stack you do not care about at a given point in time, e.g. gem code.
Tracciatto aligns with this model by allowing skip‑paths to come from multiple sources. Patterns are merged and passed to rdbg via the RUBY_DEBUG_SKIP_PATH environment variable.
Different users and teams have different needs. You may always want to skip stepping into Rails internals across all projects, while each workspace may define additional project‑specific patterns. Launch configurations can then add temporary overrides without modifying shared files, this is why there are three possible sources for skip‑paths:
1. Launch configuration
Any launch‑type configuration may define skip‑paths via the skipPaths property.
Example launch.json
{
"type": "tracciatto",
"request": "launch",
"program": "${file}",
"skipPaths": ["sorbet-runtime-*"]
}
2. Workspace file
A workspace‑level file containing one pattern per line, with lines beginning with # being ignored. The filename is controlled by tracciatto.skipPathsFileName (default: .tracciatto-skip-paths).
Skip‑path pattern format
Skip‑paths use the same glob‑style matching rules as rdbg. These are evaluated against absolute file paths.
Supported constructs:
*: match within a single path segment**: match across directory boundaries?: match a single character[abc]: character classes
Comments can be added by starting a line with # (Ruby comment). Blank lines are allowed.
Examples
# Skip all Rails internals
actionpack/**
activerecord/**
# Skip Sorbet runtime files
sorbet-runtime-*
# Skip any file ending in _spec.rb
**/*_spec.rb
# Skip vendor bundle
vendor/bundle/**
# Skip a specific file
lib/internal/debug_helpers.rb
3. Setting
The tracciatto.skipPaths setting provides an additional place to define skip‑paths, useful for global or personal preferences.
Choosing where to define skip‑paths
Use this table to decide which source fits your workflow:
| Source | Scope | Best for | Notes |
|---|---|---|---|
| Launch configuration | Per debug session | Scenario‑specific exclusions | Lives in launch.json |
| Workspace file | Per project | Shared team rules or stable project‑level patterns | Version‑controlled; one pattern per line; preferred |
| Setting | Global or workspace | Personal preferences across all projects | Great for "always skip Rails internals" |
This layered approach provides maximum flexibility: global preferences, project‑level rules, and session‑specific overrides can all coexist cleanly.
Token Replacement
Tracciatto supports the ${workspaceFolder} token as prefix on skip-paths. For example, ${workspaceFolder}/lib becomes /Users/user/project/lib, while ${workspaceFolder}lib becomes /Users/user/projectlib.
Logs
Tracciatto writes diagnostic information to the Tracciatto output channel. You can adjust the log level using Developer: Set Log Level and selecting Tracciatto. See the documentation for details.