This extension provides Ruby debugging based on the debug library. It supports both the official rdbg debug‑type and a custom tracciatto debug-type while adding several workflow and usability improvements.
-
Support for multi-root workspaces
-
Multiple concurrent Ruby debug sessions
-
Exception Filters view for managing
catchbreakpoints through the UI -
Flexible skip‑path management via launch configuration, user settings, and a workspace file
-
Customizable debug library behavior:
- Alter the maximum inspected‑string length from the default 180 characters
- Activate Set Value support for variables in the Watch and Variables views (ref)
Table of Contents
- Requirements
- Quick Start
- Getting Started
- Configuration
- Debug Configurations
- Commands
- Breakpoints
- Skip-Path Patterns
- Logs
Requirements
Tracciatto uses the Ruby debug gem and its rdbg executable.
Before debugging, make sure:
- The
debuggem is installed - The
rdbgcommand is available in yourPATH
Example:
gem install debug
For Bundler-managed projects, make sure dependencies have been installed:
bundle install
Tracciatto automatically prefers bundle exec when a Gemfile is present (enabled by default, see tracciatto.preferBundler).
Quick Start
- Open a Ruby file.
- Set a breakpoint with F9.
- Run the Tracciatto: Debug Active Editor command.
- Start debugging.
For reusable workflows, create a launch configuration.
Getting Started
Launching a debug session
Starts a Ruby script under the debugger.
Option 1: Launch configuration
-
Add a
launchconfiguration to.vscode/launch.json{ "type": "tracciatto", "request": "launch", "name": "Debug current file", "program": "${workspaceFolder}/my_script.rb" }Enable
useTerminalfor programs that read from standard input, e.g. when usinggets,readline. -
Start your debugging session using the launch configuration.
Option 2: Debug command
- Run the Tracciatto: Debug Active Editor command.
This command uses an internal debug configuration, so .vscode/launch.json is not needed or updated in any way.
Attaching to a running process
Connect to an already running Ruby process started with rdbg. To be able to attach, you must have started the process with rdbg in attach mode. Refer to the debug library documentation for details.
Example: Start a script with the debugger open on a given port
rdbg --open --port 12345 -- your_script.rb
Example: Start a script with the debugger open on a given socket
rdbg --open --sock-path /tmp/rdbg.sock -- your_script.rb
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
require 'debug/open'
In all cases, the debug library will print a DEBUGGER: Debugger can attach via ... message which includes the socket or port to attach to.
Once the port or socket is set up, you can use one of the following options to attach to it:
Option 1: Launch configuration
-
Add an
attachconfiguration to.vscode/launch.json:Example: Port mode
{ "type": "tracciatto", "request": "attach", "name": "Attach to Ruby (port)", "port": "12345" }Example: Socket mode
{ "type": "tracciatto", "request": "attach", "name": "Attach to Ruby (socket)", "socket": "/tmp/rdbg.sock" } -
Start your debugging session using the launch configuration.
Option 2: Attach To… command
-
Run the Tracciatto: Attach To… command.
-
Provide the socket path or the port to attach to.
Configuration
Tracciatto supports the following user and workspace settings:
| Setting | Description | Default |
|---|---|---|
tracciatto.forceEnableRdbgDebugType |
Force-enable built‑in rdbg debug type even when the vscode‑rdbg extension is installed but detected as inactive. Requires window reload after changing. |
false |
tracciatto.logDapMessages |
Log all Debug Adapter Protocol messages as trace entries. Normally useful only for extension or DAP debugging. This setting can be toggled at any time during a debugging session, making it more flexible than the rdbg configuration option showProtocolLog. |
false |
tracciatto.preferBundler |
Prefer running under bundle exec to run tracciatto.runtimeExecutable when a Gemfile is present and no runtimeExecutable is explicitly set in the configuration. |
true |
tracciatto.reattachDelay |
Delay (in milliseconds) before reattaching after a debug Restart call. Helps avoid races where the debug socket is not yet ready or is briefly closed and reopened. | 1000 |
tracciatto.runtimeExecutable |
Path to the Ruby executable used for debugging. | ruby |
tracciatto.skipPaths |
Additional skip‑path patterns applied when stepping in the Ruby debugger. Merged with launch configuration and project file patterns. | None |
tracciatto.skipPathsFileName |
Filename containing skip‑path patterns. May be absolute, or relative to the workspace root. | .tracciatto-skip-paths |
tracciatto.socketSearchRoot |
Directory to search for rdbg sockets when attaching. This is not needed in WSL, but in Linux rdbg only lists sockets in the current working directory. Supports ${userHome} and ${workspaceFolder} tokens. |
Debug Protocol Overrides
The 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.
| Setting | Description | Active | Default |
|---|---|---|---|
tracciatto.patchMaxInspectedValueLength |
Changes the maximum length of text returned from the debugger for inspected values. rdbg defaults this to be 180. |
Next step / evaluation | 180 |
tracciatto.patchSimpleTypeExpansion |
Prevents simple types from appearing as expandable in debugger views like Watches. | Next step / evaluation | true |
tracciatto.patchSetVariable |
Emulates setVariable support so variable values can be edited from debugger views using the Set Value action. |
Next debug session | false |
These changes are protocol‑compliant, but they modify low‑level DAP behavior and can be disabled if they cause issues.
tracciatto.patchSimpleTypeExpansion
Simple types include: Complex, BigDecimal, FalseClass, Float, Integer, NilClass, Rational, Regexp, String, Symbol, Time, and TrueClass.
tracciatto.patchSetVariable
The custom support for the Set Value action in the Watch and Variables views is sensitive to context and variable type; some values cannot be assigned. When this occurs, the Debug Console may still provide an alternative way to modify state using a Ruby expression.
The extension cannot distinguish between an exception being raised (e.g. when trying to set a frozen object) and one being returned (e.g. when setting a value to a specific exception instance), as the debugging protocol does not provide enough information.
The following error types commonly associated with invalid input are therefore always treated as failures, meaning it is not possible to assign an instance of them using Set Value: ArgumentError, FrozenError, KeyError, NameError, NoMethodError, RangeError, RuntimeError, SyntaxError, TypeError, ZeroDivisionError.
Version Managers
| 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 systemPATH.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. |
useTerminal |
Launch the debuggee in a terminal. Useful for programs that require terminal input (gets, readline, etc.). Tracciatto always uses a socket for debugging in this mode, ignoring any port configuration. |
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 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 when vscode-rdbg is installed to avoid conflicts. Use tracciatto.forceEnableRdbgDebugType if you want to experiment with Tracciatto's implementation instead. VS Code behavior means that whichever extension attempts registration second will fail, but Tracciatto handles this situation gracefully with a log entry. This setting exists so you 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 debug-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. |
useTerminal |
Launch the debuggee in a terminal. Useful for programs that require terminal input (gets, readline, etc.). Tracciatto always uses a socket for debugging in this mode, ignoring any port configuration. |
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. |
| Debug Active Editor in Terminal | Debugs the active Ruby editor inside a terminal. Useful for programs that require terminal input. |
| 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": "${workspaceFolder}/my_script.rb",
"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.