Linux/NixOS (GLF-OS): builder tools download fails with "The builder's AppImage could not be unpacked (137)" #66

Closed
opened 2026-11-14 13:57:41 +00:00 by FredM33 · 3 comments

What happens

On NixOS (GLF-OS), the launcher cannot finish step 1 ("Game files"). While it downloads "Builder tools", it stops with:

"The download stopped: The builder's AppImage could not be unpacked (137): The Longshot B..." (the message is cut off in the UI)

At the same time a dialog "Longshot Builder" appears: "The Longshot Builder has no window of its own: the Longshot Launcher builds the game and starts it. Get the launcher from https://longshot.magicbean.dev/download". "Try again" gives the same result, and "Next" stays disabled.

Environment

  • OS: GLF-OS (NixOS-based), GNOME on Wayland
  • Launcher: LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage (also seen with the rc launcher)
  • Builder tools tried: v3.0.0-rc.3 and Nightly 132 (5e072fc8) - same result
  • Launcher check: 31 GB RAM, Vulkan 1.3, mesh shaders (VRAM shown as 23.1 GB, later 8 GB)

What I tried (same result every time)

  • Launcher integrated with Gear Lever, then uninstalled and run as a plain AppImage
  • Run directly, and run through appimage-run

Observation

Running an AppImage directly from a terminal on this system prints this instead of running it normally:

$ ./LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage --appimage-extract
LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage installed in /home/<user>/.cache/appimage-run/<hash>

No squashfs-root folder is created. (I ran this on the launcher AppImage, not on the builder AppImage.)

Hypothesis (not verified)

AppImages seem to be intercepted by appimage-run on NixOS, which extracts to a cache and passes the arguments to the app, instead of treating --appimage-extract as the AppImage runtime does. If the launcher unpacks the builder AppImage that way, it would run the builder, which shows its "no window" message and returns a non-zero code.

Question

Is the NixOS case known? Could the launcher unpack the builder differently, or is there a documented workaround?

Screenshots of the error and of the dialog are attached.

## What happens On NixOS (GLF-OS), the launcher cannot finish step 1 ("Game files"). While it downloads "Builder tools", it stops with: "The download stopped: The builder's AppImage could not be unpacked (137): The Longshot B..." (the message is cut off in the UI) At the same time a dialog "Longshot Builder" appears: "The Longshot Builder has no window of its own: the Longshot Launcher builds the game and starts it. Get the launcher from https://longshot.magicbean.dev/download". "Try again" gives the same result, and "Next" stays disabled. ## Environment - OS: GLF-OS (NixOS-based), GNOME on Wayland - Launcher: LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage (also seen with the rc launcher) - Builder tools tried: v3.0.0-rc.3 and Nightly 132 (5e072fc8) - same result - Launcher check: 31 GB RAM, Vulkan 1.3, mesh shaders (VRAM shown as 23.1 GB, later 8 GB) ## What I tried (same result every time) - Launcher integrated with Gear Lever, then uninstalled and run as a plain AppImage - Run directly, and run through appimage-run ## Observation Running an AppImage directly from a terminal on this system prints this instead of running it normally: $ ./LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage --appimage-extract LongshotLauncher-nightly-48-9b3d202b-x86_64.AppImage installed in /home/<user>/.cache/appimage-run/<hash> No squashfs-root folder is created. (I ran this on the launcher AppImage, not on the builder AppImage.) ## Hypothesis (not verified) AppImages seem to be intercepted by appimage-run on NixOS, which extracts to a cache and passes the arguments to the app, instead of treating --appimage-extract as the AppImage runtime does. If the launcher unpacks the builder AppImage that way, it would run the builder, which shows its "no window" message and returns a non-zero code. ## Question Is the NixOS case known? Could the launcher unpack the builder differently, or is there a documented workaround? Screenshots of the error and of the dialog are attached.
Contributor

Same in my side

Same in my side
Contributor

Solutions to solve this

NixOS side:

programs.appimage.binfmt = false; # mkForce false; for GLFOS

Warning: You need run all appimage with appimage-run <myapp.appimage> and Desktop Application can be broken if .desktop Exec is not prefixed by appimage-run and run directly the appimage.

Project side (purposed by Claude Code but not tested):

diff --git a/Core/Toolchains.cs b/Core/Toolchains.cs
index a5e6fd8..4bbec91 100644
--- a/Core/Toolchains.cs
+++ b/Core/Toolchains.cs
@@ -340,6 +340,9 @@ public sealed class Toolchains
 
     static async Task ExtractAppImage(string image, string folder, CancellationToken cancel)
     {
+        // (a binfmt_misc handler, NixOS's programs.appimage.binfmt, takes any file with AppImage's magic to appimage-run, which
+        // unpacks it in its own cache and runs its AppRun with our arguments: without the magic the kernel runs its runtime)
+        ClearAppImageMagic(image);
         var si = new System.Diagnostics.ProcessStartInfo(image, "--appimage-extract")
         {
             WorkingDirectory = folder, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true,
@@ -354,6 +357,17 @@ public sealed class Toolchains
         if (p.ExitCode != 0) throw new IOException($"The builder's AppImage could not be unpacked ({p.ExitCode}): {error.Result.Trim()}");
     }
 
+    /// The AppImage magic ("AI" and its type, at offset 8 of the ELF header) zeroed: its runtime does not read it
+    static void ClearAppImageMagic(string image)
+    {
+        using var f = new FileStream(image, FileMode.Open, FileAccess.ReadWrite);
+        Span<byte> magic = stackalloc byte[3];
+        f.Position = 8;
+        if (f.Read(magic) != 3 || magic[0] != (byte)'A' || magic[1] != (byte)'I') return;
+        f.Position = 8;
+        f.Write(stackalloc byte[3]);
+    }
+
     static string Native(string rel) => rel.Replace('/', Path.DirectorySeparatorChar);
 
     /// A zip entry's name: relative, '/' between its parts, none of them "..", no drive or backslash
# Solutions to solve this ## NixOS side: ```nix programs.appimage.binfmt = false; # mkForce false; for GLFOS ``` **Warning:** You need run all appimage with appimage-run <myapp.appimage> and Desktop Application can be broken if .desktop Exec is not prefixed by appimage-run and run directly the appimage. ## Project side (purposed by Claude Code but not tested): ```diff diff --git a/Core/Toolchains.cs b/Core/Toolchains.cs index a5e6fd8..4bbec91 100644 --- a/Core/Toolchains.cs +++ b/Core/Toolchains.cs @@ -340,6 +340,9 @@ public sealed class Toolchains static async Task ExtractAppImage(string image, string folder, CancellationToken cancel) { + // (a binfmt_misc handler, NixOS's programs.appimage.binfmt, takes any file with AppImage's magic to appimage-run, which + // unpacks it in its own cache and runs its AppRun with our arguments: without the magic the kernel runs its runtime) + ClearAppImageMagic(image); var si = new System.Diagnostics.ProcessStartInfo(image, "--appimage-extract") { WorkingDirectory = folder, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, @@ -354,6 +357,17 @@ public sealed class Toolchains if (p.ExitCode != 0) throw new IOException($"The builder's AppImage could not be unpacked ({p.ExitCode}): {error.Result.Trim()}"); } + /// The AppImage magic ("AI" and its type, at offset 8 of the ELF header) zeroed: its runtime does not read it + static void ClearAppImageMagic(string image) + { + using var f = new FileStream(image, FileMode.Open, FileAccess.ReadWrite); + Span<byte> magic = stackalloc byte[3]; + f.Position = 8; + if (f.Read(magic) != 3 || magic[0] != (byte)'A' || magic[1] != (byte)'I') return; + f.Position = 8; + f.Write(stackalloc byte[3]); + } + static string Native(string rel) => rel.Replace('/', Path.DirectorySeparatorChar); /// A zip entry's name: relative, '/' between its parts, none of them "..", no drive or backslash ```
Contributor

EDIT: The patch works, I'm preparing PR with more clean path. Check if binfmt is enabled on the host and call only ClearAppImageMagic if binfmt is enabled.

EDIT: The patch works, I'm preparing PR with more clean path. Check if binfmt is enabled on the host and call only ClearAppImageMagic if binfmt is enabled.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/LongshotLauncher#66
No description provided.