---
title: Crash recovery (auto-resume sessions after a crash or restart)
---

# Crash recovery (auto-resume sessions after a crash or restart)

## What it is

### What it does

When Omniscio starts and detects sessions that were running last time the app exited — whether you closed it cleanly or it crashed / the OS rebooted — it automatically brings them back. You launch the app, the sidebar paints with those sessions visible immediately, and one by one they reconnect to a fresh Claude CLI child and pick up where they left off. Each revived session receives a single `"Please continue"` operator turn so the agent knows to resume; the message renders in the chat with an **auto-response badge** so you can see this was an automated revival, not the agent volunteering work or you sending a duplicate. A non-blocking toast — `"Resuming N session(s) from last shutdown"` — fires once at the start to tell you what's happening.

You don't have to click anything. You don't have to remember which sessions were open. Omniscio's job is to make the crash invisible: log files survived, conversation history survived (it's all in the local SQLite DB), and the live processes that died get respawned and re-handed the conversation transcript.

Crash and restart recovery — two flavors under the hood (the postmortem distinguishes "crash" from "restart"), identical from your POV and controlled by the same setting — are the main way Omniscio brings sessions back. One **narrower** path joins them: a session **interrupted mid-work when you closed the app** that didn't get snapshotted for restart (covered in [its own section below](#a-session-interrupted-on-close-shows-up-in-your-inbox--and-comes-back-on-reopen)). All three are gated by the same setting and look identical to you.

## Where to find it

Recovery has no panel of its own — it happens at launch, in the sidebar and in a toast, and the sessions it brings back are ordinary sessions you open like any other. There is nothing to set up before it runs: it is on the moment you install, and the single switch that governs it sits with the other session controls rather than in a screen of its own. The switch, and the toast button that stops a resume in progress, are described under How it behaves below.

## How it behaves

### When it triggers

A session qualifies for crash recovery on the next startup if **all** of these are true:

- It was in a `running` state when Omniscio last exited (or was preserved for restart via the graceful-shutdown snapshot — see [tray and window](tray-and-window.md)).
- Its `ended_at` timestamp is `NULL` in the DB (no clean termination was recorded).
- It is a genuine **app-crash victim** — it was actively running when Omniscio died, so the startup reconciler flipped it to `error` and stamped it crash-reconciled (`crash_reconciled=1`). A session that **errored on its own** (a turn failure, a dead CLI process, a non-transient API error) is NOT a crash victim and is **never** silently revived — it stays `error` (red) across the restart, exactly as it ended. (A _transient_ API 5xx that exhausts its silent retries is the exception — it auto-recovers via the recovery-failed re-arm, not dead red.) This stamp is the precise gate; the **120-second** `status_changed_at` window is kept only as a freshness bound (a true crash victim is always inside it).
- The `Auto-Resume Sessions on Restart` setting is on (default on — see below).

Sessions that don't qualify stay in their last-known state (`error`, `needs_you`, `paused`, etc.) and surface normally in your inbox. In particular, a red **errored** session stays red across a close-and-reopen — it is not turned into an amber "your turn". (Before 2026-06-09 the crash path used the 120-second window alone as a proxy for "just crashed" and could resurrect a genuine error that happened shortly before you reopened — see the [errored-sessions-resurrected-on-restart postmortem](../../.claude/memory/postmortems/errored-sessions-resurrected-on-restart-postmortem.md).)

### What you see

Watch the launch sequence from the user's POV:

1. **Second 0** — Omniscio's window opens. The sidebar paints with every recoverable session already visible, each showing the **`starting`** status (the grey dot, ringed) — deliberately grey, not green: a session that is still queued to launch is not working yet. The window is fully interactive: you can scroll, click, switch projects, open Settings, do anything. Nothing is blocking.
2. **Toast (with a Stop button)** — A blue info toast slides in: `Resuming 13 sessions from last shutdown` (or `Resuming 1 session from last shutdown` for a single session). It carries a **Stop** button and **stays up the whole time sessions are coming back** (the resume runs for minutes), so the button is there when you reach for it; it clears itself once the resume finishes. Use it as the cue "Omniscio noticed; sit tight" — or hit **Stop** to halt it (see [Stopping the resume](#stopping-the-resume-the-stop-button-and-the-auto-resume-switch)).
3. **Trickle to running** — Over the next minute or so, sessions transition from `starting → running` one at a time, with a gentle gap between each: **at least 5 seconds**, automatically stretching while your computer is still busy finishing the previous spawn's work — whether that's the CPU, the memory, the **disk** the previous revival is still hammering as it reloads its history, or Omniscio's own heartbeat reporting the app itself just stalled — in that case the next revival waits for a stall-free window (up to ~20 seconds) — and stretching more (up to ~45 seconds, held to a calmer level) around a heavyweight revival that has to replay a session's whole conversation history, since that's the most intensive kind of restart. So a big batch never slams the machine. Each revived session gets a fresh agent turn going as the `"Please continue"` message is delivered. You'll see the agent's reply stream in.
4. **Auto-response badge** — In the chat history, the `"Please continue"` message that Omniscio injected renders with an **auto-response badge** so it's visually marked as system-generated, not an action you took. You can click the badge to see the full metadata about why and when the auto-response fired.
5. **"Restoring…" line in the conversation (with a "Restart / Continue" button)** — If you open one of these sessions while it's still waiting its turn in the queue, the chat shows a small status line at its foot — _"Restoring this session from your last app close — this is automatic and may take a moment."_ — so an idle-looking panel never reads as broken. Right beside it is a **"Restart / Continue"** button — also reachable from the keyboard with **Shift+R** or **C** (the same key you use to Continue a stalled session): click it or press the key and Omniscio pulls that one session to the front of the line and starts it immediately, instead of waiting for the queue to reach it (it briefly shows "Starting…" while it kicks off). The line clears itself the instant the session reconnects, and the usual "agent is typing" dots are held back during this window so you see only the one accurate message. The same **"Restart / Continue"** action also sits in the session's **⋯ (overflow) menu** while it's waiting to relaunch — identical on phone and desktop — so it's easy to reach even if the inline line has scrolled out of view.

If you have one or two sessions to revive it'll feel instant. If you have a dozen or more, the trickle is visible but the app stays responsive the whole time — by design.

**A note on what the revived agent sees.** The badge on that `"Please continue"` is for _you_ — it renders in the transcript, and the agent never receives it. So to the agent, a revival used to be indistinguishable from you typing "Please continue" yourself, and some would answer it as if it were a fresh instruction. If you turn on **"Prevent mistaken 'nothing to do' replies"** (see [The woken no-op sentinel](woken-noop-sentinel.md)), the revival nudge now also says, in the message itself, that Omniscio sent it and not you. Leave the setting off and the text is exactly what it always was.

### Don't want to wait? Act on it and it jumps the line

The trickle is for the _background_ — it keeps a big mass-restart from freezing your machine. It is **not** a wall you have to wait behind. The moment you act on a specific session — click the **"Restart / Continue"** button (or press **Shift+R** / **C**) on its "Restoring…" line, pick **"Restart / Continue"** from the session's **⋯ (overflow) menu** (right in the session view, on phone and desktop), **send it a message**, or hit **Restart** from the dashboard menu — Omniscio pulls that one session straight to the front of the line and starts it **right then**, instead of waiting for the queue to reach it on its own. The "Restart / Continue" button is the most direct: it sits right in the session you're looking at, so you don't have to guess at sending a message or hunting a menu. If you send a message instead, your message becomes its first turn (you skip the automatic `"Please continue"` entirely). So if you reopen Omniscio and want one session back _now_, just click in — the grey "Starting" dot is a session genuinely on its way back, and acting on it does exactly what you'd expect.

The one time you'll still briefly wait: if that session happens to be the one the queue is launching at that exact moment, Omniscio won't double-start it (a second start would replace the first, and anything riding the replaced one would be lost). Your message waits for that launch instead and goes in as soon as the session is up; only if the launch takes unusually long do you see _"Restoring this session from your last app close — try again in a moment."_ Messages other agents queued for that session wait their turn the same way — they are kept and delivered, never dropped. Every other case starts immediately, however long the session has been waiting in line.

### Stopping the resume: the Stop button and the auto-resume switch

Don't want the sessions back? You have two controls, for two different needs:

- **Stop, right now (this restart only).** The **Stop** button on the "Resuming N sessions" toast halts the resume the moment you see it happening. The sessions that hadn't come back yet are left **stopped** (grey "ended") — quiet, not running, and **never** turned into a pile of "Needs You" nags — so you get a clean slate. They're still there: bring any of them back later from **Manage Sessions → Restart**, or by sending a message. Until Omniscio next starts, nothing automatic brings a stopped session back — not a scheduled check-in, a test or merge notice, a queued message, or another agent's message; those are turned away (another agent's message is kept, never lost), and only you can restart the session. (Sessions that already came back before you clicked stay running; clicking Stop just halts the rest.) Stop does **not** change any setting — the next restart still auto-resumes unless you turn that off below.

- **Turn auto-resume off (across restarts).** To stop Omniscio bringing sessions back on _every_ restart, flip the **"Resume sessions when Omniscio restarts"** switch off. It lives right in the **Manage sessions** modal (the footer), next to where you stop sessions — so you don't have to hunt through Settings. (It's the same switch as **Settings → Workflow → "Auto-Resume Sessions on Restart"** — one setting, shown in both places.) Turn it back on whenever you want resume again. With it off, nothing auto-resumes on restart — neither the graceful-shutdown snapshot nor genuine crash victims.

### When something doesn't come back

- **A launch hiccup because the machine is busy** — if a revival can't even spawn because your computer is momentarily overloaded (a _transient_ OS failure, not a real fault), Omniscio keeps relaunching it with a growing gap until it's back, instead of giving up after a few tries. This is the [relentless relaunch](relentless-relaunch.md) behavior, on by default — it's exactly what stops a big mass-restart from stranding a pile of sessions as red errors when the burst overloads the OS. Only a _genuine_ fault (next bullet) turns the session red.
- **A revived session lands in `error` after a few seconds** — The CLI child spawned but exited fast (binary missing, OAuth token rotated, project folder moved, disk full). Omniscio has a 5-second fail-fast watchdog that detects this case and retries **once more** with a forced transcript replay (replays your conversation history into the CLI so the new child has the same context). If the second attempt also fails, the session stays in `error` and you can reopen it manually to investigate.
- **A big restart is slow to finish (lots of sessions)** — A large batch comes back **one at a time** by design (the anti-freeze pacing), so dozens of sessions can take several minutes to all come back. They're still queued — watch them trickle; this is not a stall.
- **The revival never started at all** — Two safety nets bound the genuinely-stuck cases: a **progress-aware stall backstop** that gives up only if the queue stops making _any_ forward progress for ~2 minutes (a genuine wedge), and a **10-minute "queue never started" net** for the case where the launch sequence never began (e.g. the window failed to wire the queue up). Neither is a clock on _how long a big restart may take_: a queue that's healthily draining — even a 48-session restart that legitimately needs half an hour at the safe pacing — keeps re-arming the stall backstop and is **never** cut off mid-drain. If a session genuinely _is_ abandoned (a true wedge, or the queue never started), it's parked as **"your turn"** — the orange recovery-failed dot in your inbox, one-click resumable — **not** a dead-end red `error`, and never left on the dim gray "starting" color, so a dropped session is always visible and recoverable, never silently missing. (Before 2026-06-12 this backstop was a blind **15-minute hard ceiling** that guillotined the un-launched tail of a slow-but-healthy 48-session restart into dead `error` — see the [recovery-ceiling-strands-slow-restart-tail postmortem](../../.claude/memory/postmortems/recovery-ceiling-strands-slow-restart-tail-postmortem.md); and before 2026-06-09 the 10-minute net couldn't tell "wedged" from "slow" — see the [safety-net-abandons-slow-restart postmortem](../../.claude/memory/postmortems/safety-net-abandons-slow-restart-postmortem.md).)
- **You see a session in `starting` long after the toast fired** — Almost always means the per-session spawn hit the 30-second per-launch timeout and Omniscio moved on without it. The session lands in `error` on the next watchdog tick (~30s later).
- **A restart-resumed external session (Codex, DeepSeek, …) reconnects but stays silent** — a non-Claude session that resumes but produces **no first output** is force-recovered **fast** — within ~150 seconds (load-aware) — instead of waiting out the patient mid-turn stall threshold (up to ~30 min) or the 4-hour turn cap. It restarts the engine and re-drives the turn (bounded), then surfaces an honest error if it still won't respond, so a re-launched session can't sit `running` while emitting nothing for a long time (the 2026-08-12 phantom-`running` wedge, when 22 Codex sessions sat silent ~80 min after a restart). Power-user knobs: kill switch `AMC_DISABLE_RESUME_FIRST_OUTPUT_CEILING=1`, window override `AMC_CODEX_RESUME_FIRST_OUTPUT_SECONDS`. See the [codex-restart-resume-phantom-running postmortem](../../.claude/memory/postmortems/codex-restart-resume-phantom-running-postmortem.md) + `restart-resume-first-output-ceiling` in the [codex-robustness contract](../../.claude/memory/contracts/codex-robustness-contract.md).

### A session that was mid-recovery survives the restart

There's one important refinement on top of the generic `"Please continue"` revival. If a session was **in the middle of an automatic auth/rate-limit retry** when the app exited — its last turn had hit a login (OAuth 401) error or a rate limit and Omniscio was already retrying it — that in-flight recovery is now **durable**. On the next launch Omniscio resumes that specific session with its **real last instruction** (your actual last message), not the generic `"Please continue"` nudge, and it remembers how many retry attempts were already used so it doesn't start the budget over. So a crash during a retry doesn't lose your place or quietly re-nudge the agent with a meaningless turn — it picks the failed turn back up exactly where it was.

If, at that point, **every** login is dead or out of capacity and there's genuinely no healthy account to run on, the session doesn't silently spin — it lands in a visible **recovery-failed** state (an orange dot in your inbox) so you can clearly see it needs you to re-authenticate or add capacity. See [account pool](account-pool.md) for how dead logins are handled.

### A session force-closed by a busy shutdown still resumes

When you close or restart Omniscio with many sessions running, the graceful shutdown gives itself a fixed **15-second budget** to stop them all. If it runs out (a lot of busy sessions), it **force-closes** whatever's left so the app can exit — and a force-closed session is recorded as `error` (red), not a clean `ended`. Omniscio had already snapshotted those sessions as "alive at shutdown," so on the next launch they resume with the same `"Please continue"` nudge as any cleanly-closed session — **regardless of how long the app was down** — and each still passes the same finished-work check, so one that had genuinely finished isn't re-nudged.

Before this fix, a force-closed `error` session could fall through both recovery nets — the crash path's 120-second window had passed, and the restart path only accepted cleanly-`ended` sessions — and strand as a red `error` row until you reopened it by hand. See the [please-continue-after-clean-shutdown postmortem](../../.claude/memory/postmortems/please-continue-after-clean-shutdown-postmortem.md) (R6).

### A session cut off in the last seconds of a close still resumes

Closing Omniscio marks each working session "paused — will resume on restart" first, and only a few seconds later shuts its agent down. An agent can start new work inside that gap — say its background build finishes and it begins reading the result. That step is cut off by the shutdown, and Omniscio now records it as **interrupted**, so the session comes back on reopen like any other paused session. The same holds when the agent had written a long, finished-looking report but never got to signal the end of its turn before being shut down.

Before this fix (2026-09-25), such a cut-off step could be recorded as a finished answer: the session then sat in **Needs You** looking done, its last message stopping mid-step, and it did not resume on its own. A step that genuinely finished before the shutdown still counts as finished and is never re-nudged. See the [please-continue-after-clean-shutdown postmortem](../../.claude/memory/postmortems/please-continue-after-clean-shutdown-postmortem.md) (R10).

The same gap covers two more cases (since 2026-09-26):

- **A session that was waiting on you when you closed, but started work by itself in the gap** — for example, the background job it was waiting on finished and it began reading the result. Its cut-off step is recorded as interrupted and the session is marked "paused — will resume on restart", so it comes back on reopen instead of sitting in **Needs You**. A session that genuinely needs you — a question, an approval, a stop you made — is left exactly as it was.
- **A Dev Pipeline gate that finished in the gap.** Omniscio approves a green gate by itself when that gate is set to auto-approve, but a step that finishes while the app is closing can't receive that "approved". On reopen the gate is now approved within a few minutes instead of first waiting out the usual safety delay (4 minutes, or 15 on a busy machine) — and still only when nothing else stops it: you haven't replied since, the gate is still set to auto-approve, and its report still reads ready.

### A session interrupted on close shows up in your inbox — and comes back on reopen

There's a narrower gap the two paths above don't cover. When Omniscio closes and a session was **genuinely mid-work** but did **not** get snapshotted for restart — it wasn't an app-crash victim AND wasn't in the graceful-shutdown save-set (for example, a second app-close suspended it) — it used to be left `ended` and **invisible**: a dim gray row in your **Live** list, out of the Needs-You inbox entirely, so the only way it came back was you finding it and resuming it by hand.

Now such a session is handled two ways at once:

- **It surfaces in the sidebar's Interrupted section.** On close it's flipped to an **Interrupted** state (an ember/orange dot — the same family as paused / rate-limited), so it's always findable instead of a gray ghost in Live. This happens **regardless** of the Auto-Resume setting. (As of 2026-08-21 an interrupted-on-close session collects in **Interrupted**, not Needs You — Needs You is now reserved for sessions that delivered a real message and need your response; see [interrupted-sessions-section.md](interrupted-sessions-section.md).)
- **It comes back on its own.** On the next launch, if Auto-Resume is on, Omniscio resumes it with the same `"Please continue"` nudge as any other revived session and it returns to `running`. If Auto-Resume is off, it just waits for you in the Interrupted section as the safety net.

The guardrail is the same finished-work check the other paths use: only a session that was **genuinely mid-work** is surfaced or resumed this way — a session the agent had actually **finished** is never flipped to Interrupted and never re-nudged ("closed means closed"). See the [please-continue-after-clean-shutdown postmortem](../../.claude/memory/postmortems/please-continue-after-clean-shutdown-postmortem.md) for why re-nudging a finished session is the exact failure this guards against.

**This covers your non-Claude engines too.** A **Codex, Gemini, Pi, OpenCode, Cursor, Antigravity, or Hermes** session interrupted mid-work no longer strands as a dim gray "finished" row on restart — it surfaces in **Needs You** exactly like a Claude session and, with Auto-Resume on, comes back on its own through that engine's own resume path (it re-registers the session and replays its conversation / uses the engine's own `--resume`, never `claude --resume`). Only **OpenClaw** is deliberately left out — a remote gateway whose connection is gone once the app closes, so it genuinely can't reconnect. (The per-turn engines Cursor / Antigravity / Hermes _used_ to be left out on the theory they "never strand gray" — but they did strand as **finished** on a normal restart, which is exactly the bug this now fixes.) Whatever the engine had streamed before the close is preserved.

You can also force one of these back immediately with **Restart stuck sessions** ([bulk restart](bulk-stop-restart-sessions.md)) — an Interrupted session is a valid Restart target.

### A session Omniscio couldn't start comes back on the next restart

Sometimes a session goes red not because its agent hit a problem but because **Omniscio itself couldn't start it** — the launch failed before the agent ever ran. After the next restart Omniscio brings each of these back **once**, on its own, picking up where it left off. A session whose agent genuinely failed still stays red until you look at it, exactly as before.

- If that one attempt fails too, the session stays red with a note in its conversation — *"This session couldn't be automatically resumed after Omniscio restarted"* — and Omniscio stops trying, so it never loops. Send it a message to pick it back up.
- A session you **closed, stopped, or paused** is never brought back this way, and nothing is while you've pressed **Stop** on the "Resuming sessions" toast or turned auto-resume off (see below).

### How to turn it off

**Settings → Workflow → Auto-Resume Sessions on Restart** is a toggle, default **on**. Helper text: _"Automatically restart sessions that were active when the app was closed or crashed. Running sessions receive a continue nudge. Sessions waiting for your input are restored."_

Turn it off if you'd rather every crashed session show up in your inbox as `error` for manual triage instead of being silently revived. Sessions that were waiting for your input (`needs_you`) are restored regardless of this toggle — only the auto-resume of `running` sessions is gated by it.

The setting key is `autoResumeOnCrash` (boolean). It's also available via the CLI control surface for external AI agents that manage Omniscio settings.

## Related

This page is split across two parts: [part 2](crash-recovery-part-2.md) covers the crash-loop circuit breaker, the silent-death watchdog, the states that are deliberately never resumed and why the revival trickles, plus the code map. Two of the behaviours here have pages of their own — the relaunch that keeps trying while the machine is busy is [relentless relaunch](relentless-relaunch.md), and a session the app hands back to you is described in [interrupted sessions](interrupted-sessions-section.md). Restarting a batch by hand is on [bulk stop and restart](bulk-stop-restart-sessions.md), and what survives a graceful close is on [tray and window](tray-and-window.md).
