TracciattoThis extension provides Ruby debugging using the debug library. It supports the official Some of the unique features offered by this extension:
Additionally, the extension can patch certain debug library behaviors through configuration, including:
This is not a fork of the VS Code Ruby rdbg Debugger extension. That extension has been incredibly valuable in my daily work and is greatly appreciated. While its implementation has been referenced, Tracciatto follows a distinct design philosophy. This is evident in the code, and several requested features have naturally emerged due to this design or have been straightforward to implement. Development tends to favor the attach‑based debugging scenario because it is the one I use daily. Feedback on other scenarios is always welcome.
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. |
program |
Ruby file to debug (required). |
runtimeExecutable |
Ruby command to run (ruby by default). |
rdbgPath |
Optional absolute path to rdbg. |
skipPaths |
Paths to skip when stepping. |
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. |
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. |
rdbgPath |
Optional absolute path to rdbg. |
skipPaths |
Paths to skip when stepping. |
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.
By default, Tracciatto's built‑in
rdbgsupport is automatically disabled when thevscode‑rdbgextension is installed. This prevents conflicts where both extensions attempt to register the same debug type.
If needed, the setting tracciatto.forceEnableRdbgDebugType allows forcing Tracciatto's built‑in rdbg support even when vscode‑rdbg is installed, as long as it is detected as inactive. VS Code does not provide a reliable way to determine another extension's activation state or distinguish between "Disabled" and "not yet activated", so enabling this setting may cause both extensions to attempt registration. In that case, whichever extension registers second will fail registration; Tracciatto, however, handles this situation gracefully. This option exists so users experimenting with Tracciatto can simply disable vscode‑rdbg instead of uninstalling it.
Debug‑type detection happens during extension activation, so you must reload the window after installing, uninstalling, enabling, or disabling vscode‑rdbg. 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. |
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 |
[hostname:]port 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 host:port or socket. When exactly one workspace folder is open, it is used as one source for skip-paths. In multi‑root workspaces no folder is selected. The tracciatto.skipPathsFileName setting is always used as it comes from user settings. |
| 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)
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 its catch command, but provides significant advantages as these are applied automatically at the start of any type of debugging session, they can be easily toggled at any point, and you can maintain a custom list of exceptions specific to your project.
Exceptions are categorized into two distinct groups:
- Built‑in Filters: common Ruby exception classes offered by default; they are disabled by default and they cannot be edited or removed.
- User Filters: custom list of Ruby exception classes (e.g.,
NoMethodError,KeyError,ActiveRecord::RecordNotFound) you define for the current workspace.
Exception filters can be toggled at any point in time, with the extension either applying in the next debug session start/launch or applying to the currently running ones.
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.