Stacks

Trace a Runtime Bug From a Stack Trace in Ruby with Atlas (2026)

Updated 9 min read

A Ruby backtrace is a list of file:line pairs, which is exactly what Atlas's read tool consumes. To trace a runtime bug from a stack trace in Ruby, paste the backtrace into Atlas and have it read each frame at the reported offset, starting with the topmost app/ frame rather than the gem frames underneath it. If read reports Offset <n> is out of range for this file, the trace came from a different build and the line numbers cannot be trusted, so Atlas re-reads the file from the top before believing anything. Atlas then greps for the error message string to find where it is constructed, which is usually more informative than the top frame, uses the lsp tool's findReferences operation to see which callers can reach the failing method with bad input, fixes with edit, and locks the behavior with an RSpec example.

How does Atlas read a Ruby stack trace?

A Ruby backtrace is a list of file:line pairs such as app/services/invoice_builder.rb:42:in `build', and Atlas's read tool consumes exactly that. Atlas reads each frame at its reported offset, so the failing line and its surrounding method body enter the session directly, with no debugger attached and no repro environment required.

The practical order matters. A Ruby backtrace usually opens with frames inside gems installed by Bundler, and those are rarely where the bug is. The frame worth reading first is the topmost one inside your own app/ or lib/ tree, because that is where the bad value was passed in. Atlas reads that frame at its offset, then walks outward through the caller frames the trace lists, reconstructing the path that produced a nil where an Invoice was expected. Atlas indexes code by AST declarations using tree-sitter rather than blind line windows, so when a frame lands mid-method, Atlas can pull the whole def rather than a truncated window.

What if the Ruby line numbers in the backtrace do not match the file?

If Atlas's read tool reports Offset <n> is out of range for this file, the Ruby backtrace came from a different build than the code on disk. Atlas validates offsets against the current file, so a stale trace fails loudly instead of confidently showing you line 187 of app/models/invoice.rb as the culprit.

Stale traces are the quiet killer of production debugging. A backtrace captured from a deploy two weeks ago references line 187 of a file that has since lost 40 lines, and reading line 187 today produces a method that has nothing to do with the failure, which sends the whole investigation somewhere plausible and wrong. Atlas refuses to guess. When the offset does not exist in the current file, read errors, and the correct response is to re-read the file from the top and locate the method by name, or to check out the revision the trace actually came from. Atlas reads git branches, status, and diffs, so identifying the deployed commit is part of the same session.

Why grep for the Ruby error message instead of reading the top frame?

Atlas greps for the error message string to find where it is constructed, which is usually more informative than the top frame of a Ruby backtrace. A raise ArgumentError, "invoice must have a customer" in app/services/ names the invariant that was violated, while frame 1 only names the line that noticed.

Ruby's most common runtime failures illustrate this well. NoMethodError: undefined method `total' for nil:NilClass tells you a receiver was nil, and the frame tells you where the method was called, but neither tells you where the nil came from. Grepping for the message text finds the raise site when the error was explicit, and grepping for the attribute name finds the assignment sites when it was not. Atlas searches with hybrid semantic and keyword retrieval fused by reciprocal rank fusion, so a query like "where is the customer association set on an invoice" can find the code even when the literal string does not appear.

How does Atlas find which Ruby callers can reach the failing method with bad input?

Atlas uses the lsp tool's findReferences operation on the failing Ruby method to enumerate every caller that can reach it, then reads each callsite to see which ones can pass the bad input. A backtrace shows 1 path into the method. findReferences shows all of them, including callers in lib/ and in Rakefile tasks.

One backtrace is one sample. The bug reproduced through a controller action, but the same method may also be reachable from a background job and from a Rake task, and if any of those can pass the same bad value, fixing only the controller path leaves the bug alive. Atlas enumerates the callers, reads them, and reports which ones are exposed. That inventory also shapes the fix: if three of five callers can pass nil, the guard belongs inside the method, and if only one can, the guard belongs at that callsite. Every Atlas tool call is permission-gated against allow, ask, and deny rules, so this reading phase can be allowed while every edit still asks.

How do you lock in a Ruby fix so the same stack trace cannot recur?

Atlas fixes the Ruby bug with edit and adds 1 regression test so the trace cannot recur silently. The RSpec example asserts on the exact condition that produced the backtrace, an invoice built without a customer, and it fails against the unfixed code before it passes against the fixed code.

A fix without a test is a fix that will be undone. Atlas writes the RSpec example into spec/services/invoice_builder_spec.rb next to the existing examples, matching the repo's conventions rather than inventing new ones, and runs RSpec through the bash tool so the test is executed rather than merely written. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so both the fix in app/ and the new example in spec/ are reviewed before they land. Run RuboCop on the touched files afterward, and let Bundler resolve any gem the fix needed, so the commit is clean and the backtrace is closed for good.

How do you set up Atlas on a Ruby project in 2026?

Run atlas in a Ruby project with a Gemfile in 2026 and let Atlas read your modules, gems, and Rakefile tasks. Atlas is a terminal-native TUI, so it runs where you already run bundle exec rspec. Have Atlas write RSpec examples or extract a module, then review the diff before it lands.

Because Atlas reads the Gemfile, it sees which gems Bundler has resolved, which matters when a backtrace descends into gem code and the question is whether the bug is yours or the library's. Atlas snapshots file changes as git patches, so a speculative fix to app/services/invoice_builder.rb can be diffed and rolled back if the RSpec example still fails. For Ruby teams that cannot send source to a hosted model, Atlas can build its code index with local Ollama embeddings, keeping code off third-party servers while still supporting semantic search over the app/ and lib/ trees.

Step by step

  1. 01Run atlas in the Ruby project that contains the Gemfile, and let it read your modules, gems, and Rakefile tasks.
  2. 02Paste the Ruby backtrace and have Atlas read each frame's file at the reported offset, starting with the topmost frame inside app/ or lib/ rather than the Bundler gem frames beneath it.
  3. 03If read reports Offset <n> is out of range for this file, treat the trace as coming from a different build: re-read the file from the top and locate the method by name before trusting any line number.
  4. 04Grep for the error message string, for example the text of a raise ArgumentError, to find where the error is constructed, which is usually more informative than the top frame.
  5. 05Run the lsp tool's findReferences operation on the failing method to enumerate every caller that can reach it, including background jobs and Rakefile tasks the backtrace never showed.
  6. 06Decide where the guard belongs from that caller inventory: inside the method if several callers can pass the bad value, at the callsite if only one can.
  7. 07Fix the code with edit and approve the unified diff Atlas surfaces before it writes to app/.
  8. 08Add an RSpec regression example under spec/ that reproduces the original condition, run RSpec through bash to prove it passes, then run RuboCop on the touched files.

Frequently asked questions

how to debug a Ruby production stack trace without a debugger
Paste the backtrace into Atlas. Its read tool consumes file:line pairs directly, so it reads each frame at its reported offset, greps for the error message to find where it is raised, uses the lsp tool's findReferences to enumerate callers, fixes with edit, and locks the behavior with an RSpec example.
what does Offset is out of range for this file mean in Atlas
Atlas validates backtrace offsets against the current file. Offset <n> is out of range for this file means the Ruby trace came from a different build than the code on disk, so the line numbers are stale. Re-read the file from the top or check out the deployed revision.
which frame of a Ruby backtrace should I read first
Read the topmost frame inside your own app/ or lib/ tree, not the gem frames Bundler installed beneath it. The bad value was almost always passed in from your code, and the gem frame is only where it finally failed.
how do I find where a Ruby NoMethodError on nil actually comes from
The frame tells you where the method was called on nil, not where the nil came from. Grep for the attribute or association name to find the assignment sites, and use Atlas's semantic search, which fuses keyword and semantic retrieval with reciprocal rank fusion, when the literal string does not appear.
does Atlas work with Bundler and RSpec projects
Yes. Run atlas in a project with a Gemfile and it reads your modules, gems, and Rakefile tasks. Atlas runs RSpec through its bash tool, so a regression example is executed rather than merely written, and RuboCop can be run on the touched files afterward.
how do I know if a Ruby bug is reachable from more than one place
Run the lsp tool's findReferences operation on the failing method. A single backtrace shows one path in, but findReferences shows every caller, so a bug reachable from a controller, a background job, and a Rake task is fixed once rather than three times.
can I roll back a fix Atlas made to a Ruby file
Yes. Atlas snapshots file changes as git patches, so a speculative fix to a file under app/services/ can be diffed and rolled back if the RSpec example still fails. Every edit is also shown as a unified diff for approval before it is written.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Trace a Runtime Bug from a Stack Trace with Atlas in 2026

How to trace a runtime bug from a stack trace with Atlas in 2026: read each frame at its offset, grep for the error string, and use the lsp tool to find callers.

Debug a Single Failing Test in Ruby with Atlas (2026)

Debug a single failing RSpec example in Ruby with Atlas in 2026. Run the spec in isolation with bash, walk the call path with lsp, and fix the code, not the assertion.

Locate Where a Behavior Is Implemented in Ruby with Atlas (2026)

Find the exact Ruby file and method behind a behavior in 2026. Atlas combines codebase_search, grep, read, and lsp across your Gemfile, app tree, and RSpec suite.

Review a Pull Request in Ruby with Atlas (2026)

Review a Ruby pull request in 2026 with Atlas: bash produces the raw patch, read pulls whole files, findReferences checks callers, and RSpec and RuboCop close the loop.

Upgrade a Ruby Dependency and Fix Breakage with Atlas in 2026

Upgrade Ruby gems and fix breaking changes with Atlas in 2026. Atlas drives Bundler, reads RSpec output, and repairs code, ensuring your Ruby projects stay current and functional.

Write unit tests for untested code in Ruby with Atlas (2026)

Add RSpec coverage to an untested Ruby module in 2026 with Atlas: enumerate methods with lsp documentSymbol, copy the repo's spec conventions, then run the suite.

Rename a Symbol Across a Ruby Repo with Atlas (2026)

How Atlas renames a Ruby method, class, or constant repo-wide in 2026: lsp findReferences for the true reference set, grep for strings, edit with replaceAll, RSpec to prove it.

Run Atlas Headless in CI for Ruby Projects in 2026

Automate Atlas in your Ruby CI/CD pipelines by 2026. Get machine-readable output for RSpec, Bundler, and RuboCop tasks, ensuring safe, non-interactive code generation.

Browse this resource hub