diff --git a/scripts/build-desktop-artifact.test.ts b/scripts/build-desktop-artifact.test.ts index b7383de236aa..8c77e0b4910b 100644 --- a/scripts/build-desktop-artifact.test.ts +++ b/scripts/build-desktop-artifact.test.ts @@ -481,6 +481,12 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => { assert.deepStrictEqual((linux.linux as Record).protocols, [ { name: "T3 Code", schemes: ["t3code", "t3code-dev"] }, ]); + // The AppImage must be built with the static runtime toolset. + // electron-builder's default ("0.0.0") emits a runtime dynamically + // linked against libfuse.so.2, which FUSE 3-only distros cannot mount. + assert.deepStrictEqual(linux.toolsets, { appimage: "1.0.3" }); + assert.notProperty(mac, "toolsets"); + assert.notProperty(win, "toolsets"); for (const config of [mac, linux, win]) { assert.deepStrictEqual(config.electronLanguages, DESKTOP_ELECTRON_LANGUAGES); assert.deepStrictEqual(config.files, DESKTOP_FILE_EXCLUSIONS); diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts index bf36029bc75b..87d0ed66bb0a 100644 --- a/scripts/build-desktop-artifact.ts +++ b/scripts/build-desktop-artifact.ts @@ -2108,6 +2108,14 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* ( } if (platform === "linux") { + // Pin the static AppImage toolset. electron-builder's default for + // `toolsets.appimage` is the legacy "0.0.0" bundle, whose type-2 runtime + // is dynamically linked against libfuse.so.2; distros that ship only + // FUSE 3 (Ubuntu 24.04+, Debian trixie/forky) can no longer mount it and + // the AppImage dies with `dlopen(): error loading libfuse.so.2` before + // Electron starts. The 1.0.3 bundle uses runtime 20251108, which is + // statically linked and needs no FUSE at all. + buildConfig.toolsets = { appimage: "1.0.3" }; buildConfig.linux = { target: [target], executableName: "t3code",