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

> Atlas's bash tool races every JavaScript command against a timeout and distinguishes a genuinely slow build from one silently blocked on interactive input.

To diagnose a hanging JavaScript command with Atlas, read the shell_metadata block that Atlas's bash tool returns when the command is killed. Atlas is the terminal-native AI coding agent, and its bash tool races every command against a timeout. When the timeout expires, Atlas tells you exactly what happened and what to do: retry with a larger timeout if the command is expected to take longer and is not waiting for interactive input. That second clause is the diagnosis. A pnpm install waiting on a prompt or a vitest process sitting in watch mode never resolves by waiting, so more time is the wrong answer.

## Key takeaways

- Atlas's bash tool races every JavaScript command against a timeout and reports what happened in a shell_metadata block.
- The diagnosis is binary: retry with a larger timeout if the command is expected to take longer and is not waiting for interactive input.
- A blocked command never resolves by waiting, so re-run with non-interactive flags (-y, --no-input, CI mode), such as `vitest run` instead of watch mode.
- A genuinely slow command, like a cold pnpm install, just needs a larger timeout value in milliseconds.
- If you interrupted the command, the metadata says User aborted the command, which is not a timeout.
- Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so you control which commands execute at all.

## Why is my pnpm or vitest command hanging?

A hanging JavaScript command is one of 2 things: genuinely slow, or silently blocked on interactive input. Atlas's bash tool races every command against a timeout, and when the timeout expires Atlas says to retry with a larger timeout if the command is expected to take longer and is not waiting for interactive input.

The distinction is the whole diagnosis, because the two cases have opposite remedies. A cold `pnpm install` in a large monorepo genuinely takes minutes, and the fix is more time. A `vitest` process that dropped into watch mode, or a package script waiting on a y/n confirmation, will sit there forever, and more time changes nothing. Atlas's message names the interactive-input case explicitly rather than leaving you to guess, which is why reading it beats staring at a stalled terminal. Run atlas where your package.json lives, so the npm scripts and bundler config the command depends on are all in scope.

## What is the shell_metadata block in Atlas's bash output?

The shell_metadata block is what Atlas's bash tool returns alongside the output of every command. When a JavaScript build or a vitest run is killed, that block holds the reason: a timeout expiry with the instruction to retry with a larger value in milliseconds, or the note that the User aborted the command. In 2026 it is the first thing to read.

Reading the metadata rather than the stdout is the habit worth forming. Stdout from a hung `pnpm run build` may end mid-line, or show nothing at all if the bundler buffers, and there is no way to tell from the visible text whether the process was killed, crashed, or is still waiting. The shell_metadata block resolves that ambiguity. It distinguishes an expired timeout from an abort you triggered yourself, which matters because those two look identical in the output stream but call for completely different next steps.

## How do I stop a JavaScript command from waiting on input?

Re-run the blocked command with non-interactive flags: -y, --no-input, or CI mode. In a JavaScript project that means `vitest run` rather than vitest watch mode, and CI mode so pnpm and the bundler never stop to ask a question no one is there to answer. In 2026 a command blocked on stdin is still the most common cause.

Agent sessions have no human at the keyboard of the child process, so any prompt is a permanent stall. The common culprits in a JavaScript repo are predictable. A test command that defaults to watch mode holds the terminal open by design. A package script that confirms before overwriting a file waits forever. A dependency installer that asks about a peer conflict does the same. Passing the non-interactive form is a one-time fix per command, and it is worth writing the non-interactive variant into the scripts block of package.json so the next agent session and CI both get it right by default.

## How do I give a slow JavaScript build more time?

Retry with a larger timeout value in milliseconds, exactly as Atlas's message instructs. The Atlas bash tool takes the timeout as a parameter, so in 2026 a cold `pnpm install` or a full production bundle can be given the minutes it honestly needs rather than being killed at a fixed default.

Slow is not the same as broken, and JavaScript builds are frequently slow for legitimate reasons: a cold pnpm store, a large dependency graph, a bundler doing a full production pass over hundreds of modules. Once the shell_metadata block confirms the command was not blocked on input, raising the timeout is the correct and complete fix. Pass the value in milliseconds. If the same command keeps needing a longer window, that is a signal about the build itself rather than about Atlas, and it belongs in a todo rather than in a larger and larger timeout.

## How do I tell an abort from a timeout in Atlas?

Atlas distinguishes the 2 cases explicitly. If you aborted a running JavaScript command yourself, the shell_metadata says User aborted the command, which separates your interrupt from an expired timeout. Without that distinction, a cancelled `pnpm run build` and a build that ran out of time would be indistinguishable in the output.

The separation matters for what the agent does next. A timeout suggests the command needs more time or is blocked, and Atlas should investigate. An abort means you made a decision, and the right response is to stop, not to retry with a bigger timeout. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so which commands the agent may execute at all is under your control from the start. Once a build is working again, run prettier before committing so the diff shows the actual change to package.json or the bundler config rather than a reformat.

## Steps

1. Run atlas where your package.json lives so the JavaScript npm scripts, bundler config, and pnpm workspace are in scope.
2. Run the command through the bash tool and read the shell_metadata block in the output when it is killed.
3. Decide from the message whether the command is slow or blocked: Atlas explicitly calls out the interactive-input case rather than leaving you to guess.
4. If it is blocked, re-run with the tool's non-interactive flags (-y, --no-input, CI mode), for example running `vitest run` instead of letting vitest sit in watch mode.
5. If it is genuinely slow, such as a cold `pnpm install` or a full production bundle, retry with a larger timeout value in milliseconds as the message instructs.
6. If you aborted it yourself, note that the metadata says User aborted the command, which distinguishes your interrupt from a timeout.
7. Write the non-interactive variant into the scripts block of package.json so the next session and CI both get it right by default.
8. Once the command runs clean, run prettier so the diff to package.json or the bundler config is about the change and not about formatting.

## FAQ

### why does my vitest command hang forever in an ai agent session

vitest sitting in watch mode holds the terminal open by design, and no one is at the keyboard of the child process. Re-run with `vitest run` or CI mode so the command exits on its own.

### pnpm install times out in atlas

Read the shell_metadata block. If the command is not waiting for interactive input, a cold pnpm install is simply slow, so retry with a larger timeout value in milliseconds as Atlas's message instructs.

### how do i tell if a command is slow or stuck waiting for input

Atlas's bash tool tells you. When the timeout expires it says to retry with a larger timeout if the command is expected to take longer and is not waiting for interactive input, which names the blocked case explicitly.

### what is shell_metadata in atlas bash output

The shell_metadata block accompanies bash output and records what happened to the process, including whether a timeout expired or the User aborted the command.

### how do i make npm scripts non-interactive for an ai coding agent

Pass the tool's non-interactive flags (-y, --no-input, CI mode) and write the non-interactive variant into the scripts block of package.json, so both agent sessions and CI avoid prompts that nobody can answer.

### atlas killed my javascript build, was it a timeout or did i cancel it

Check the metadata. If you aborted it, Atlas says User aborted the command. An expired timeout produces a different message with instructions to retry with a larger timeout.

### can i raise the bash timeout in atlas

Yes. The timeout is a parameter on the bash tool, given in milliseconds, so a long production bundle or a cold pnpm install can be given the time it honestly needs.

---

Canonical HTML: https://runatlas.sh/resources/stacks/diagnose-a-hanging-or-long-running-command-in-javascript
Source of truth: aeo_pages row `/resources/stacks/diagnose-a-hanging-or-long-running-command-in-javascript` (segment: Stacks) (this file is generated from it, never hand-edited).
Licence: Atlas is proprietary with a free core. It is not open source and there is no public source repository.
