Debugging one failing Rust test starts by shrinking the problem: Atlas runs just that test with `cargo test` and a name filter, so the panic and its assertion are 20 lines instead of thousands. Atlas then reads the test and the module it exercises, walks the call graph with the lsp tool's goToDefinition and findReferences operations, and only then edits. Because Atlas's bash tool is a real shell, every lever you would reach for by hand is available: a focused filter, a verbose flag, or temporary logging. The target is the production code in your crate, never the assertion.
How do I isolate one failing Rust test instead of running the whole crate?
Filter it. Atlas runs the failing test through its bash tool with `cargo test` plus a name filter, which compiles the crate once and runs 1 test, so the panic message and the failing assertion are the only output you have to reason about.
Debugging needs a signal small enough to hold in your head. A whole-crate run buries one panic under every unrelated module in the Cargo.toml workspace. A filtered run gives you the assertion, the panic, and nothing else. Atlas's bash tool is a real shell, so the invocation is exactly what you would type yourself, and cargo behaves exactly as it does outside the agent.
How do I find the Rust code a failing assertion actually exercises?
Walk the call graph. Atlas reads the failing Rust test and the module it exercises, then uses the lsp tool's goToDefinition operation to jump from the call into the function, and a 2nd time into the trait impl that supplied the behavior when the function merely delegates.
A Rust panic tells you the value was wrong. It does not tell you which impl block produced it, and in a crate built on traits that is exactly the missing fact. goToDefinition resolves a call to a trait method into the concrete impl. findReferences answers the reverse: which other callers in the crate reach this code with similar input, and are they quietly broken too. Atlas indexes code by AST declarations using tree-sitter, not blind line windows, so a jump lands on the fn, the impl, or the struct rather than mid-way through a long module.
How do I check a hypothesis about a failing cargo test?
Instrument the failing cargo test and re-run just that 1 test. Atlas adds temporary logging with the edit tool, or re-runs through bash with a verbose flag such as `-- --nocapture`, because `cargo test` captures stdout by default and a `println!` inside the code under test otherwise prints into the void.
Rust debugging is mostly about seeing intermediate values, and the borrow checker means you frequently cannot simply stash one in a variable and inspect it later. Printing is the practical lever, and it requires the verbose flag to be visible. Because the logging goes in through edit, the instrumentation shows up as a diff you approved rather than as an invisible mutation of your crate, and Atlas snapshots file changes as git patches so removing it afterward is exact rather than from memory.
When should Atlas use apply_patch instead of edit in a Rust crate?
When the fix spans several hunks. Atlas fixes production code with the edit tool, but a Rust change that adjusts a lifetime, updates a match arm, and touches 2 callers in the same module is a multi-hunk change, and chaining sequential edits against shifting content is where mistakes creep in.
Rust fixes spread by design. Satisfying the borrow checker at one site forces a signature change, which forces every caller in the module to change with it, and each sequential edit runs against a file the previous edit already rewrote, so the oldString you planned may no longer exist. apply_patch lands the whole multi-hunk change as one unit. Whichever tool applies it, the change belongs in the crate, not in the assertion: a test relaxed until it passes has destroyed the only evidence the bug existed.
How do I confirm a Rust fix without breaking the rest of the crate?
Widen the net after the filtered run goes quiet. Re-run the single `cargo test` filter first for fast feedback, then the full suite, because Rust changes propagate through the type system and a fix that satisfies 1 test can violate a trait bound relied on elsewhere in the crate.
Confirm the crate still compiles with `cargo build` if the change touched public signatures. Then clean up: the temporary `println!` you added behind `-- --nocapture` must not reach review, and the git patch snapshot makes reverting exactly that instrumentation straightforward. Run rustfmt last so the final diff shows the borrow-checker fix rather than a reformat of half the module. Atlas reads git branches, status, and diffs, and can stage and create commits on your behalf.
Step by step
- 01Run atlas in a crate with a Cargo.toml so the Rust modules, traits, and cargo workspace are in scope.
- 02Run just the failing test with the bash tool using `cargo test` plus a name filter, so the panic and its assertion are the only output to reason about.
- 03Read the test and the module it exercises, then use the lsp tool's goToDefinition operation to jump from the call into the function and on into the trait impl.
- 04Use the lsp tool's findReferences operation on the failing function to see which other callers in the crate reach it with similar input.
- 05Form a hypothesis and check it: add temporary logging with edit, or re-run the single test through bash with a verbose flag such as `-- --nocapture`, since cargo test captures stdout by default.
- 06Fix the production code with edit; when the change spans several hunks, such as a lifetime plus a signature plus its callers, use apply_patch rather than chaining brittle edits.
- 07Re-run the filtered `cargo test`, then the full suite, and confirm the crate compiles with `cargo build` if public signatures changed.
- 08Remove the temporary logging, run rustfmt, and commit the fix to the crate rather than a relaxed assertion.
Frequently asked questions
- how to run only one failing test in rust
- Have Atlas run `cargo test` with a name filter through its bash tool. Isolating the test leaves you with a single panic and assertion instead of output from every module in the workspace.
- cargo test not printing println output
- `cargo test` captures stdout by default. Re-run the filtered test through Atlas's bash tool with a verbose flag such as `-- --nocapture`, since the bash tool is a real shell and passes flags straight through.
- how do i find which trait impl a failing rust test actually calls
- Use the lsp tool's goToDefinition operation to jump from the call into the function and on into the concrete impl, then findReferences to see which other callers reach the same code.
- should i change the assertion to make a rust test pass
- No. Fix the crate, not the assertion. A test relaxed until it goes quiet destroys the only evidence the bug existed, and the defect ships anyway.
- when should i use apply_patch instead of edit
- When a Rust fix spans several hunks, such as a lifetime change plus a signature plus its callers. apply_patch applies the whole change as one unit rather than chaining edits against shifting content.
- how do i remove debug logging added while fixing a rust test
- Atlas snapshots file changes as git patches so edits can be diffed and rolled back, which makes removing exactly the temporary println straightforward. Run rustfmt afterward.
- does a rust fix need the whole suite re-run
- Yes. Rust changes propagate through the type system, so a fix that satisfies one filtered `cargo test` can violate a trait bound elsewhere. Run the full suite and `cargo build` before committing.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Debug a Single Failing Test with Atlas in 2026
How to debug one failing test with Atlas in 2026: run it in isolation with bash, walk the call graph with the lsp tool, and fix the code, not the assertion.
Atlas for Rust in 2026
Adopt Atlas, the terminal-native AI coding agent, for Rust development in 2026. Tackle borrow checker errors and clippy lints with Atlas's secure, approval-gated assistance.
Write Unit Tests for Untested Code in Rust with Atlas (2026)
How Atlas writes cargo test coverage for an untested Rust module in 2026: lsp documentSymbol lists every pub item, grep copies your conventions, and the tests actually run.
Plan a Multi-File Change Before Editing in Rust with Atlas (2026)
Design a Rust refactor across crates with the Atlas plan agent, which blocks every edit tool until you approve. Then let cargo test, cargo, and rustfmt confirm it.
Self-review your working diff before committing in Rust with Atlas (2026)
How Atlas self-reviews your working Rust diff before committing in 2026: read the whole diff, grep for leftovers, revert from snapshots, then run cargo test and rustfmt.
Diagnose a Hanging or Long-Running Command in Rust with Atlas (2026)
Is your cargo build slow or silently blocked on stdin? Atlas races every command against a timeout in 2026 and tells you which one it is, plus how to get unstuck.
Upgrade a dependency and fix the breakage in Rust with Atlas (2026)
Bump a crate to a new major version in 2026 and let Atlas repair the fallout: cargo output read by the agent, release notes fetched, callsites fixed, cargo test green.
Onboard to an Unfamiliar Rust Codebase with Atlas in 2026
Onboard to an unfamiliar Rust codebase in 2026. Atlas reads your Cargo.toml, modules, traits, and cargo workspace, then ranks crates with codebase_search.