invoke-ai / invoke-ai/launcher

[bug]: Update prompt cannot be declined and can kill a running Invoke session or in-progress install

Open
#153 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
48
Forks
23
Avg merge
1m
Merged PRs (30d)
1

Description

## Summary

When a launcher update finishes downloading, the "Update downloaded and ready to install" prompt has exactly one button and its result is discarded — `autoUpdater.quitAndInstall()` runs unconditionally on every way out of the dialog. There is no way to decline or defer, and no check for whether Invoke is running or an install is in progress, so a background update can terminate a live session with no warning.

Present on `main` today. Found while reviewing #142, but unrelated to it.

## The code

`src/main/updater.ts` (end of `checkForUpdates`):

```ts
await dialog.showMessageBox(mainWindow, {
type: 'info',
title: 'Update Downloaded',
message: 'Update downloaded and ready to install.',
buttons: ['Restart and Install'],
});

autoUpdater.quitAndInstall();
```

The returned `{ response }` is not destructured and not checked. With a single button, `cancelId` defaults to `0`, so dismissing with Esc or the window close button also resolves to `0` and falls straight through to `quitAndInstall()`. There is no "Later" button.

## Reproduction

1. Have a launcher update available. On startup, `checkForUpdates` prompts; click **Download**.
2. `await autoUpdater.downloadUpdate()` runs unbounded — a 100MB+ installer can take minutes on a slow link.
3. During the download, start Invoke and begin working (or start a multi-GB install).
4. The download completes. The "Update downloaded" dialog appears with one button.
5. Click it, press Esc, or close the dialog — all three reach `autoUpdater.quitAndInstall()`.
6. `quitAndInstall()` → `app.quit()` → `before-quit` → `cleanup()` → `cleanupInvoke()` kills Invoke / `cleanupInstall()` cancels the install.

## Impact

- The user cannot decline or defer the restart — the only escape is killing the launcher process.
- An in-flight generation is lost, or a multi-GB install is cancelled, with no warning that either was running.
- `app.on('before-quit', cleanup)` is `async` and Electron does not await it (the existing `TODO(psyche)` at `src/main/index.ts`), so `quitAndInstall()` has already spawned the platform installer while `exitInvoke()` is still inside `commandRunner.kill(10_000)`. The installer and Invoke's SIGTERM shutdown race.

## Suggested fix

Two parts, both small:

1. Give the dialog a real choice and honour it:
```ts
const { response } = await dialog.showMessageBox(mainWindow, {
type: 'info',
title: 'Update Downloaded',
message: 'Update downloaded and ready to install.',
buttons: ['Restart and Install', 'Later'],
defaultId: 0,
cancelId: 1,
});
if (response !== 0) {
return; // electron-updater installs on next quit anyway
}
```
2. Warn when work is in flight. The invoke manager already exposes `isProcessRunning()`, and the install manager has a status — if either is active, say so in the `detail` so the user knows what restarting will stop, rather than discovering it afterwards.

Worth noting that #142 adds a close-confirmation for exactly this class of "you're about to lose a running Invoke" mistake, but it cannot help here: `quitAndInstall()` goes through `app.quit()`, which sets `isQuitting` before any window close, so the confirmation is intentionally skipped. This path needs its own guard.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in src/main/updater.ts at the end of checkForUpdates, then read the invoke and install managers for their running-status APIs. Check src/main/index.ts and its before-quit cleanup TODO to understand the shutdown path. Done means the prompt supports Restart and Install or Later, reports active work before restarting, and does not quit when the prompt is dismissed or deferred.

Written by the indexing model from the issue text.

Assessment

Tech stack
electron, typescript
Domain
desktop
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.