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
- Ensure downloadAndInstall is only invoked after a successful update check.
- Gate the update action on updater availability state in the UI.
- 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
- Never call install steps out of sequence — always via downloadAndInstall after check()
- Verify Tauri updater plugin config and signing keys in packaged builds
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
- Download function not available.
- Cannot currently handle remotes as start position
- Failed to create runtime
- Failed to parse response
- Request failed
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)