gitbutlerapp/gitbutler · error

Install function not available.

Error message

Install function not available.

What it means

Thrown by the updater's private install() when this.backendInstall is unset. Like backendDownload, the backend install function is only registered when a real, downloadable update exists and the platform supports installation. Installing without it is an invalid updater state.

Solutions

  1. Ensure downloadAndInstall is only invoked after a successful update check.
  2. Gate the update action on updater availability state in the UI.
  3. Check that the Tauri updater plugin and its signing/public-key configuration are present in a packaged build.
Defensive patterns

Strategy: validation

Validate before calling

if (!updater.isUpdateAvailable()) return; // install only after download is prepared

Try / catch

try {
  await updater.downloadAndInstall();
} catch (e) {
  showToast('Update installation is not available');
}

Prevention

When it happens

Trigger: downloadAndInstall() reaching the install step when backendInstall was never set — i.e. install invoked without a prepared update (updater unavailable, dev mode, no checked update).

Common situations: Same as error 25: dev builds, missing Tauri updater plugin configuration, unsupported platform, or calling install out of sequence.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/e7bdb9a489887271. Report an issue: GitHub.

Appendix: source

Thrown at apps/desktop/src/lib/updater/updater.ts:171

		} finally {
			this.loading.set(false);
		}
	}

	private async download() {
		if (!this.backendDownload) {
			throw new Error("Download function not available.");
		}
		this.setStatus("Downloading");
		await this.backendDownload((progress: DownloadEvent) => {
			this.setStatus(downloadStatusMap[progress.event]);
		});
		this.setStatus("Downloaded");
	}

	private async install() {
		if (!this.backendInstall) {
			throw new Error("Install function not available.");
		}
		this.setStatus("Installing");
		await this.backendInstall();
		this.setStatus("Done");
	}

	private setStatus(status: InstallStatus) {
		this.update.update((update) => {
			return { ...update, status };
		});
	}

	async relaunchApp() {
		try {
			await this.backend.relaunch();
		} catch (err: unknown) {
			handleError(err, true);
		}

View on GitHub (pinned to 58e5313667)