Atlas diagnoses a hanging Python command by racing it against a timeout in its bash tool and then telling you exactly what happened. When the timeout expires, Atlas's message says to 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 pytest run or a uv install blocked on stdin never resolves by waiting, so the fix is a non-interactive flag, not a longer timeout. Atlas reads the shell_metadata block and tells the two cases apart.
Is my Python command slow or is it waiting for input?
Atlas answers that question from the bash tool's shell_metadata block. Atlas races every command against a timeout and, when it expires, says to retry with a larger timeout if the command is expected to take longer and is not waiting for interactive input. Those are the only 2 possibilities, and they have opposite fixes.
The job is to work out whether a build or script is genuinely slow or silently blocked on input, and get it unstuck. A slow Python command finishes if you wait: a pytest suite with a thousand integration cases, a uv sync resolving a large dependency graph, a data script chewing through a Parquet file. A blocked Python command never finishes: pip is waiting on a confirmation, a script called input(), a package manager is prompting to overwrite something. Waiting longer on the second case burns your afternoon. Atlas tools this workflow uses are bash and read.
What does the shell_metadata block tell you about a killed Python command?
Atlas reads the shell_metadata block in the bash output whenever a Python command is killed. The block distinguishes 3 outcomes: the command hit the timeout, the command exited with a code, or the message says User aborted the command, which means you interrupted it rather than the timeout firing.
Metadata removes the guessing. A killed pytest run and a pytest run you cancelled with a keystroke look identical in the terminal scrollback, and confusing them sends you looking for a performance problem that does not exist. Atlas's bash tool records what happened as structured metadata alongside the output, so User aborted the command is distinguishable from a timeout, and a timeout is distinguishable from a non-zero exit. Read that block first, before forming any theory about why your uv or pytest invocation did not come back. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so nothing executes unannounced in the first place.
How do you stop a Python command from blocking on stdin?
Atlas re-runs a blocked Python command with the tool's non-interactive flags, and there are usually 3 to try: -y, --no-input, or CI mode. A uv or pip command waiting on a confirmation prompt hangs forever under an agent, because no human is at the keyboard to press y.
Agents have no stdin to offer, so any Python tooling that expects a prompt is a deadlock rather than a delay. The fix is to remove the prompt. Package operations get their confirmation flag. Scaffolding tools get their CI or no-input mode. A script that calls input() gets an argument or an environment variable instead, which is worth changing permanently since the same hang will bite your CI runner exactly as hard as it bit Atlas. Once the prompt is gone, the command either completes or reveals that it was genuinely slow, and at that point the timeout is the right lever.
How do you set a bigger timeout for a slow pytest run?
Atlas retries a genuinely slow Python command with a larger timeout value in milliseconds, exactly as the bash tool's message instructs. A pytest suite with heavy fixtures or a uv sync over a cold cache legitimately takes 5 minutes, and killing it at a default timeout produces a partial log and no answer.
Timeouts are an argument you set deliberately, not a default you inherit. Atlas passes a generous timeout in milliseconds to the bash tool when the command is known to be expensive, so a full pytest run reaches its summary instead of dying halfway through the third fixture. The decision is only correct once you have ruled out the blocked-on-input case, because raising the timeout on a command waiting for a y keystroke just makes the hang last longer. Diagnose first with the shell_metadata block, then raise the timeout if and only if the command is doing real work.
Which Python commands hang most often under an AI agent?
In Python projects the 3 usual suspects are a package manager waiting on a confirmation, a pytest run that opens an interactive debugger on failure, and a script that calls input() behind a code path you did not expect. All 3 look identical from outside: no output, no exit, no clue, until the shell_metadata block explains it.
A pytest suite configured to drop into a debugger on failure will sit at a prompt forever under an agent, so running with that behavior disabled is the fix, not a longer timeout. A uv or pip operation that wants a confirmation needs its non-interactive flag. And a Python script with a stray input() call, often inside an error branch nobody exercises, blocks on the one run that hits it. Atlas reads the command's own output with the read tool when the log was written to a file, so the last line before the silence is visible even when the process never returned.
How do you fix the hang permanently in a Python repo?
Atlas fixes a recurring Python hang at the source, and there are 2 places to fix it: the offending input() call, or the project's own scripts where the non-interactive flag belongs. A hang that bites Atlas today bites your CI runner tomorrow, because neither has a human at the keyboard.
Diagnosing the same hang twice is a waste. When a Python script prompts inside a code path, replace the input() call with an argument or an environment variable so the script is scriptable. When a package command needs a confirmation flag, put the flag in the project's documented command so every runner uses it. Atlas computes a unified diff for every file edit and surfaces it for approval before writing, so a change to a script under scripts/ or to pyproject.toml is reviewed before it lands. Prove the change with a pytest run through bash, format with ruff format, and confirm the command now exits cleanly rather than hanging.
Step by step
- 01Run the Python command through Atlas's bash tool, for example pytest or uv sync, and read the shell_metadata block in the output when it is killed.
- 02Decide from the message whether the command is slow or blocked: Atlas explicitly calls out the interactive-input case, saying to retry with a larger timeout only if the command is not waiting for interactive input.
- 03Check for User aborted the command in the metadata, which means you interrupted the run yourself rather than the timeout firing, and is a different problem entirely.
- 04If the Python command is blocked, re-run with the tool's non-interactive flags (-y, --no-input, CI mode) so it cannot prompt for a confirmation that no agent can answer.
- 05If a pytest run is dropping into an interactive debugger on failure, disable that behavior rather than waiting, since a debugger prompt never resolves without a human.
- 06If the command is genuinely slow, retry with a larger timeout value in milliseconds, as the message instructs, so a heavy pytest suite or a cold uv sync reaches its summary.
- 07Use the read tool on the saved log file when output was written to disk, so the last line before the silence is visible even though the process never returned.
- 08Fix the hang permanently: replace a stray input() call with an argument or environment variable, run ruff format on the changed file, and review the unified diff Atlas surfaces before approving.
Frequently asked questions
- why does my python script hang forever with an AI coding agent
- The script is almost certainly waiting on stdin, and an agent has no keyboard to answer with. Atlas's bash tool races the command against a timeout and its message explicitly calls out the interactive-input case, so you re-run with a non-interactive flag rather than waiting longer.
- how do I tell if a command is slow or blocked on input
- Read the shell_metadata block in Atlas's bash output. Atlas says to 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 whole diagnosis, because a blocked command never resolves by waiting.
- how do I increase the command timeout in an AI agent
- Retry with a larger timeout value in milliseconds, which is exactly what Atlas's bash message instructs. Do it only after ruling out a stdin block, since raising the timeout on a command waiting for a y keystroke just makes the hang last longer.
- why does pytest hang instead of failing
- A pytest run configured to drop into an interactive debugger on failure will sit at a prompt forever under an agent. Disable that behavior rather than raising the timeout. Atlas's bash tool distinguishes the timeout case from a normal exit in its shell_metadata block.
- what does user aborted the command mean in atlas
- The metadata says User aborted the command when you interrupted the run yourself, which distinguishes your interrupt from a timeout firing. Reading that first prevents you from hunting a performance problem that never existed.
- how do I stop uv or pip from prompting during an automated run
- Pass the tool's non-interactive flags, such as -y, --no-input, or CI mode, so the command cannot prompt for a confirmation no agent can answer. Wire the flag into the project's documented command so your CI runner does not hit the same hang.
- how do I see the output of a python command that never finished
- Use Atlas's read tool on the saved log file when output was written to disk, so the last line before the silence is visible even though the process never returned. That final line usually names the prompt or the fixture the run stalled on.
- should I remove input() calls from python scripts
- Yes, if the script is meant to be run by anything other than a human. Replace the input() call with an argument or an environment variable, run ruff format on the changed file, and review the unified diff Atlas surfaces before approving the write.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Diagnose a Hanging or Long-Running Command with Atlas in 2026
How to diagnose a hanging command with Atlas in 2026: the bash tool races every command against a timeout and tells you whether it is slow or blocked on input.
Atlas for Python in 2026
Atlas is a terminal-native AI coding agent for Python in 2026. Run it in a repo with a pyproject.toml or requirements.txt and review every diff before it lands.
Run the Test Suite and Triage the Failures in Python with Atlas (2026)
How Atlas runs pytest and triages a wall of Python failures in 2026: bash truncates at 2000 lines, saves the full log, and grep groups failures into a todowrite list.
Refactor a legacy module in Python with Atlas (2026)
Refactor a legacy Python module with Atlas in 2026: enumerate callsites with lsp findReferences, restructure with apply_patch, and prove behavior with pytest.
Locate Where a Behavior Is Implemented in Python with Atlas in 2026
Find the exact Python file and symbol behind a behavior in 2026. Atlas attacks it with codebase_search, grep over ripgrep, and the lsp tool's findReferences.
Review a pull request in Python with Atlas (2026)
Review a Python pull request in 2026 with Atlas: read the changed .py files in full, check callers with findReferences, and run pytest before you approve the diff.
Run Atlas Headless in CI in a Python Repo: The 2026 Guide to atlas run
Run Atlas headless in CI on a Python repo in 2026. Use atlas run with --format json, pre-approve tools, and gate the pipeline on pytest, uv, and ruff format.
Plan a Multi-File Change Before Editing in Python with Atlas in 2026
Plan a multi-file Python change before editing in 2026. Atlas's plan agent denies edit for every path except .atlas/plans/*.md, then plan_exit hands off to build.