galaxyproject / galaxyproject/loom

Orbit exits with Electron `FATAL ... Failed to shutdown` instead of quitting cleanly

Open
#431 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
14
Forks
12
Avg merge
6d 5h
Merged PRs (30d)
17

Description

## Report

Orbit died with an Electron fatal during shutdown rather than quitting
cleanly. The tester couldn't tie it to a specific action -- the tail of the
process log is all they had:

```
[agent] ← event: agent_end {"type":"agent_end","messages":[{"role":"user","content":[{"type":"text","text":"Hello!"}], ...
[NNNNN:0817/HHMMSS.NNNNNN:FATAL:electron/shell/browser/electron_browser_main_parts.cc:523] Failed to shutdown.
Killed
```

Environment: Orbit 0.5.1, Linux x64 (WSL), Electron 41.7.1, Node 24.15.0.

`electron_browser_main_parts.cc:523 Failed to shutdown` is Electron's
`CHECK` when the browser process can't complete its shutdown sequence -- it
aborts the process instead of exiting. So this is a *quit-path* failure, not a
crash mid-session, and the `Killed` line right after suggests the process was
reaped rather than exiting on its own.

## What might be going on

Speculative, but there's a concrete suspect in our own quit path.
`AgentManager.stop()` (`app/src/main/agent.ts`) is what both `before-quit` and
`window-all-closed` call, and it:

- sends a single `SIGTERM` to the brain process,
- does **not** escalate to `SIGKILL`, and
- does **not** walk the brain's process tree.

That last point is the interesting one, because the `abort()` path right below
it *does* walk the tree and SIGKILL after a 3s grace, specifically because
pi's abort flag doesn't reach a long-running tool subprocess (#64). A quit while
a tool subprocess is alive therefore leaves descendants attached that `stop()`
never signals. The session that produced this log had been running local
conda/R tool work.

Also worth ruling in or out: Orbit starts with `--no-sandbox --no-zygote`
(`app/src/main/main.ts`), and `--no-zygote` changes how renderer children are
parented and torn down.

Not asserting either is the cause -- this needs a reproduction before anyone
writes a fix.

## What would help

1. Try to reproduce: quit Orbit while a long local `bash` tool call is still
running, on Linux/WSL. Then quit with the agent idle, as a control.
2. If it reproduces, the shape of the fix is to make `stop()` as thorough as
`abort()` -- tree-walk + SIGTERM, grace period, SIGKILL -- and have
`before-quit` wait for it.
3. Independently: we swallow this failure today. The user only saw it because
they were tailing the process output. A crash on quit should leave something
behind we can read.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with app/src/main/agent.ts and compare AgentManager.stop() with the abort() path, then inspect app/src/main/main.ts for the Electron shutdown flags. Reproduce on Linux/WSL while a long local bash tool call is running, using an idle-agent quit as a control. Done means the shutdown failure is reproduced or ruled out and its relationship to lingering process descendants is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, typescript
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.