Stacks

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

Updated 9 min read

Atlas debugs a single failing JavaScript test by running that one test in isolation with the bash tool, usually pnpm vitest run src/auth/token.test.js with a -t filter so the output is small enough to reason about. Atlas then reads the assertion and the module it exercises, walks the call path with the lsp tool's goToDefinition and findReferences operations, and only then edits. The goal is to fix the JavaScript code, not to loosen the assertion until it passes.

How does Atlas debug a single failing JavaScript test?

Atlas debugs one failing JavaScript test with 5 moves: run just that test with pnpm vitest and a -t filter through the bash tool, read the assertion, walk the call path with the lsp tool, form and check a hypothesis, then fix the module rather than the expectation.

The job is to find why one specific test fails and fix the code, not the assertion. Atlas starts by shrinking the problem. A full vitest run across a JavaScript monorepo prints thousands of lines, and no model reasons well over that. Running pnpm vitest run src/auth/token.test.js -t "refreshes an expired token" produces a handful of lines: the expected value, the received value, and a stack frame pointing into src/auth/token.js. Atlas tools this workflow uses are bash, read, lsp, edit, and apply_patch. Because bash is a real shell, the same debugging levers you would use by hand, extra console.log lines, a focused test filter, a verbose flag, are all available inside the session.

How do you run one vitest test in isolation with pnpm?

Atlas runs a single JavaScript test through the bash tool with the framework's filter flag, for example pnpm vitest run src/auth/token.test.js -t "refreshes an expired token". Filtering to 1 test keeps the output small enough to reason about instead of drowning the session in a full suite log.

JavaScript projects hide their real test command in package.json, so Atlas reads the scripts block first and uses what is actually defined rather than guessing. If the repo defines a test:unit script, pnpm test:unit is the honest entry point and the -t filter still applies. Atlas passes the path to the exact spec file, which in a JavaScript repo is typically a .test.js or .spec.js file living beside the module or under a __tests__ directory. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so the vitest invocation through bash stops for approval unless you have allowed pnpm commands in advance.

How does Atlas trace a failing JavaScript assertion back to the code?

Atlas reads the failing JavaScript test and the module it exercises, then uses the lsp tool's goToDefinition and findReferences operations to walk the call path. A vitest assertion diff names 2 things, the expected value and the received value, and the lsp tool turns that gap into a chain of real files.

JavaScript makes the call path hard to eyeball, because a value can arrive through a default export, a re-export barrel in index.js, a CommonJS require, or an ESM import rewritten by your bundler config. Rather than guessing, Atlas calls goToDefinition on the function the assertion touched and lands on the real implementation, then calls findReferences to see every callsite that can reach it. Atlas searches code with hybrid semantic and keyword retrieval fused by reciprocal rank fusion, and Atlas indexes code by AST declarations using tree-sitter, not blind line windows, so the function you care about is retrieved as a declaration rather than as a lucky 20-line window.

How do you test a hypothesis about a failing JavaScript test?

Atlas forms a hypothesis about the JavaScript failure and then checks it 2 ways: adding temporary logging with the edit tool, or re-running through the bash tool with a verbose flag. Guessing is cheap and wrong, so Atlas confirms the actual runtime value before changing any production module.

Typical JavaScript hypotheses are specific and testable. An async function was called without await, so a Promise is compared against a plain object. A callback fired after the assertion ran. A Date or a floating point value differs by milliseconds. Atlas adds a temporary console.log inside src/auth/token.js with edit, re-runs pnpm vitest run src/auth/token.test.js -t "refreshes an expired token" through bash, and reads what actually arrived. Because bash is a real shell, a verbose flag or an environment variable prefix works exactly as it would in your own terminal. Every temporary log is removed before the change is finished.

How does Atlas fix the JavaScript code without touching the assertion?

Atlas fixes the JavaScript production module with the edit tool, and when the change spans 3 or more hunks Atlas uses apply_patch instead of chaining brittle edits. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so you see the change to src/auth/token.js before it lands.

Loosening the assertion is the failure mode this workflow exists to prevent. If the test says an expired token should refresh, and it does not, the bug is in src/auth/token.js, not in expect(). Atlas edits the module. When the fix touches an async chain across several functions, for example converting a callback to async and await and updating each caller, apply_patch applies the whole set as one patch rather than five fragile string replacements. Run pnpm exec prettier --write on the changed files afterwards so the diff does not carry formatting noise into review.

How do you verify a JavaScript test fix and clean up?

Atlas re-runs the single JavaScript test with pnpm vitest and the -t filter, confirms it passes, then runs the full vitest suite to catch collateral damage. Atlas also removes every temporary console.log added during the hunt, which is step 5 of the documented workflow and the one most often skipped.

Verification in a JavaScript repo has two levels. The narrow one is the single vitest test that started red and must end green under exactly the same command. The wide one is the full suite through pnpm, because a fix inside a shared module such as src/auth/token.js can break a browser bundle test that never appeared in the filtered run. For review, Atlas snapshots file changes as git patches so edits can be diffed and rolled back, and Atlas reads git branches, status, and diffs, so the fix and its verification land as one reviewable commit rather than a pile of unexplained edits.

Step by step

  1. 01Run just the failing JavaScript test with the bash tool using vitest's filter flag, for example pnpm vitest run src/auth/token.test.js -t "refreshes an expired token", so the output is small enough to reason about.
  2. 02Read the package.json scripts block first so Atlas uses the repo's real test command instead of guessing at one.
  3. 03Read the failing .test.js file and the module it exercises, then use the lsp tool's goToDefinition and findReferences operations to walk the call path through your imports and re-export barrels.
  4. 04Form a hypothesis (an unawaited Promise, a callback firing late, a stale bundler alias) and check it by adding a temporary console.log with edit or re-running with a verbose flag through bash.
  5. 05Fix the production JavaScript module with edit; if the change spans several hunks, such as converting a callback chain to async and await, use apply_patch instead of chaining brittle edits.
  6. 06Review the unified diff Atlas surfaces before approving the write to src/.
  7. 07Run pnpm exec prettier --write on the changed files so formatting noise stays out of the diff.
  8. 08Re-run the single test with pnpm vitest, then the full suite, and remove every temporary console.log you added.

Frequently asked questions

how do I run a single failing test in vitest
Pass the spec path plus vitest's -t filter, for example pnpm vitest run src/auth/token.test.js -t "refreshes an expired token". Atlas runs exactly this through its bash tool so the output stays small enough to reason about instead of printing the whole JavaScript suite.
can an AI agent debug a failing javascript test for me
Yes. Atlas runs the single test with bash, reads the assertion and the module it exercises, walks the call path with the lsp tool's goToDefinition and findReferences operations, and then edits the production code. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs.
why does my javascript test compare a promise instead of a value
An async function called without await returns a Promise, so the assertion compares a Promise against a plain object. Confirm it by adding a temporary console.log with Atlas's edit tool and re-running pnpm vitest with the -t filter, then fix the missing await in the module rather than relaxing the expectation.
how do I stop an AI agent from just changing the assertion to make a test pass
The point of this workflow is to find why one specific test fails and fix the code, not the assertion. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so an edit that touches expect() instead of src/ is visible in the diff before it lands.
does atlas work with pnpm workspaces and package.json scripts
Yes. Run atlas where your package.json lives and let Atlas map your modules, npm scripts, and bundler config. Atlas reads the scripts block and uses the repo's real command, so pnpm test:unit is used when that is what the project defines.
how do I find every caller of a javascript function
Use the lsp tool's findReferences operation, which Atlas calls directly during debugging. Atlas also searches code with hybrid semantic and keyword retrieval fused by reciprocal rank fusion and indexes code by AST declarations using tree-sitter, so callers hidden behind barrel re-exports still surface.
how do I clean up console.log statements an AI agent added while debugging
Removing temporary logging is the final documented step of the workflow, and Atlas snapshots file changes as git patches so edits can be diffed and rolled back. Run pnpm exec prettier --write on the changed files and review the git diff before committing.
should I use apply_patch or edit for a javascript fix
Use edit for a single hunk and apply_patch when the fix spans several hunks, such as converting a callback chain to async and await across a module and its callers. Chaining brittle edits across many sites is exactly what apply_patch replaces.

Try Atlas in your terminal

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

Install Atlas

Related 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 JavaScript in 2026

In 2026, Atlas empowers JavaScript developers with a terminal-native AI coding agent. It indexes code by AST, uses local embeddings, and offers permission-gated tools for safe, efficient development.

Diagnose a Hanging or Long-Running JavaScript Command with Atlas (2026)

Is your pnpm or vitest command slow or silently blocked on input? In 2026 Atlas races every command against a timeout and tells you which of the two it was.

Run the Test Suite and Triage the Failures in JavaScript with Atlas (2026)

How Atlas runs vitest and triages a red JavaScript suite in 2026: bash saves the full log past 2000 lines, grep groups the causes, todowrite tracks each fix.

Rename a symbol across the repo in JavaScript with Atlas (2026)

Rename a JavaScript function, class, or constant repo-wide in 2026 with Atlas: lsp findReferences for real callsites, grep for strings and docs, edit with replaceAll.

Automate GitHub issue and pull request triage in JavaScript with Atlas (2026)

Run Atlas from GitHub Actions on a JavaScript repo in 2026. The atlas github command checks actor permission, requires a MODEL and PROMPT, and refuses stray comments.

Write Unit Tests for Untested JavaScript Code with Atlas (2026)

Atlas enumerates a JavaScript module's exports with the lsp tool, copies your existing vitest conventions, writes the spec file, and runs vitest with the bash tool.

Refactor a Legacy Module in JavaScript with Atlas (2026)

Refactor a legacy JavaScript module with Atlas in 2026: enumerate callsites with the lsp tool, restructure with apply_patch, and prove behavior with vitest.

Browse this resource hub