Atlas throws SessionBusyError, carrying the sessionID, because SessionRunState.assertNotBusy guards mutating operations: revert, unrevert, and startShell all assert the session is idle first, so concurrent writes to the same session are rejected rather than interleaved. The fix is to wait for the current generation to finish, or cancel it with the TUI interrupt binding, then retry. Do not work around it by opening a second session against the same worktree.
Why does Atlas throw SessionBusyError
Atlas throws SessionBusyError because SessionRunState.assertNotBusy guards mutating operations on a session that is already generating. The error carries the sessionID, and in the 2026 source revert, unrevert, and startShell all assert the session is idle before they will touch it.
SessionBusyError is a concurrency guard, not a crash. A generating session is actively producing messages and may be writing files, so allowing a revert to run underneath it would interleave two writers against the same state. SessionRunState.assertNotBusy refuses that instead. The sessionID on the error tells you exactly which session is occupied, which matters when you are running several sessions at once and only one of them is mid-generation. The three operations that trip it are the mutating ones: reverting, unreverting, and starting a shell in a session that is already generating.
How to fix SessionBusyError in Atlas
Fix SessionBusyError in Atlas by waiting for the current generation to finish, or by cancelling it, then retrying. There are only 2 ways out, wait or cancel. SessionRunState.assertNotBusy rejects the call while the session is busy, so the same revert or unrevert succeeds once the session returns to idle.
Waiting is often the whole fix, especially for a generation that is close to done. When you do not want to wait, cancel with the TUI interrupt binding: SessionRunState.cancel exists precisely for this, and it returns the session to a state where mutating operations are allowed again. After the cancel lands, re-issue the revert, unrevert, or startShell call that failed. There is no flag to force the write through while the session is busy, and that is intentional, because concurrent writes to the same session are rejected rather than interleaved.
How to cancel a generating Atlas session
Cancel a generating Atlas session with the TUI interrupt binding. SessionRunState.cancel exists precisely for this case, and cancelling is the faster of the 2 exits from SessionBusyError when you do not want to wait for the current generation to finish on its own.
Cancellation stops the in-flight generation and releases the guard that SessionRunState.assertNotBusy enforces. Atlas is a terminal-native TUI rendered with SolidJS through the OpenTUI renderer, so the interrupt is a keybinding in the interface rather than a signal you send to the process from outside. Cancel, confirm the session has settled, then retry the operation. Be honest about what cancelling costs: the model turn in progress ends where it ends, so any partial reasoning in that turn is discarded, and you may need to re-ask the question afterward.
How to handle a busy Atlas session from the server API
If you are driving Atlas from the server API, poll for the session to leave the running state before issuing the write. SessionRunState.assertNotBusy guards 3 operations, revert, unrevert, and startShell, and rejects each of them against a generating session with SessionBusyError carrying the sessionID.
API callers hit this more often than TUI users, because a script has no visual cue that a generation is in flight and will happily fire a write the instant the previous request returns. Build the wait into the client: check the session state, back off, and only then send the mutating call. Treat SessionBusyError as a retryable signal rather than a fatal one, since the same request succeeds once the session is idle. The sessionID on the error is what you key your retry against when your client is managing several sessions concurrently.
Should I open a second Atlas session on the same worktree
Do not work around SessionBusyError by opening a 2nd Atlas session against the same worktree. SessionRunState.assertNotBusy rejects concurrent writes to 1 session deliberately, and a second session on the same files reintroduces exactly the interleaving that the guard exists to prevent.
Two sessions editing one worktree will fight over the same files, and neither one has a view of what the other is doing. Atlas snapshots file changes as git patches so edits can be diffed and rolled back, and Atlas computes a unified diff for every file edit and surfaces it for approval before writing, but neither of those protections is designed to arbitrate between two independent sessions writing the same paths at once. If you need parallel work, give each session its own worktree, or fan the work out to subagents from a single session instead.
How to fix it
- 01Wait for the current generation to finish, or cancel it, then retry the operation.
- 02Cancel with the TUI interrupt binding; SessionRunState.cancel exists precisely for this.
- 03If you are driving Atlas from the server API, poll for the session to leave the running state before issuing the write.
- 04Do not work around it by opening a second session against the same worktree.
Frequently asked questions
- how to fix SessionBusyError in Atlas
- Wait for the current generation to finish, or cancel it with the TUI interrupt binding, then retry. SessionRunState.assertNotBusy rejects revert, unrevert, and startShell while the session is generating.
- why can I not revert while an Atlas session is generating
- SessionRunState.assertNotBusy guards mutating operations. Revert, unrevert, and startShell all assert the session is idle first, so concurrent writes to the same session are rejected rather than interleaved.
- how do I cancel a running Atlas generation
- Use the TUI interrupt binding. SessionRunState.cancel exists precisely for this, and cancelling returns the session to idle so mutating operations are allowed again.
- what does the sessionID on SessionBusyError tell me
- SessionBusyError carries the sessionID of the session that is busy, which identifies exactly which session is mid-generation when you are running several at once.
- how should the Atlas server API handle a busy session
- Poll for the session to leave the running state before issuing the write. Treat SessionBusyError as retryable, since the same revert or unrevert succeeds once the session is idle.
- can I run two Atlas sessions on the same worktree
- Do not do it as a workaround for SessionBusyError. Two sessions writing the same files reintroduce the interleaving the busy guard prevents. Use a separate worktree per session instead.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Atlas for Electron: Terminal-Native AI Coding for Main, Preload, and Renderer in 2026
Atlas is a terminal-native AI coding agent for Electron in 2026, where the main and renderer split, contextIsolation, and preload bridges are the security model.
Atlas with IBM Granite 3.3 8B (Ollama): the Free Local small_model for 2026
IBM Granite 3.3 8B (Ollama) is a 4.9GB general model with 128K tokens (131,072) of context, Free (self-hosted). Assign it to small_model in Atlas. Setup and limits.
Atlas with Amazon Nova Micro in 2026: The Cheapest Model on Bedrock
Amazon Nova Micro costs $0.035 per Mtok input, the lowest price in the Bedrock catalog, with a 128K token context. Use it as Atlas's small_model, never as the build loop.
Atlas vs Trae: AI Coding Agents in 2026
Atlas and Trae offer distinct AI coding agent experiences in 2026. Atlas provides terminal-native control and local data privacy, while Trae offers a full IDE with SOLO Builder and cloud tasks.
Atlas with DeepSeek Coder V2 16B Lite (Ollama): The 160K Local Agent Model in 2026
DeepSeek Coder V2 16B Lite (Ollama) gives Atlas a 160K token context from an 8.9GB download, Free (self-hosted). Setup, MoE speed, and the KV cache catch, for 2026.
Atlas for Swift in 2026
Atlas for Swift in 2026 empowers developers with a terminal-native AI coding agent. Index code by AST, ensure privacy with local embeddings, and review changes with unified diffs.
Atlas with GLM-5.2: A 1M Token Open-Weights Model at $1.40 per Mtok (2026)
GLM-5.2 drives Atlas on a 1M token context at $1.40 / $4.40 per Mtok. Z.ai's June 2026 flagship, the first GLM to reach 1M, with open-weights lineage.
Atlas with GLM-5.1: Reasoning, Cost, and Context in 2026
GLM-5.1 from Z.ai drives Atlas with a 200,000 token context at $1.40 per Mtok input and $4.40 per Mtok output. Setup, honest tradeoffs, and how it compares to GLM-5.2.