#6892·lutris

Windows exe installs intermittently fail with wine "could not open working directory" — only via Lutris, not via direct umu-run

Author: careb0tCreated Sep 14, 2026Updated Sep 17, 2026

Summary

Launching a Windows executable through Lutris via umu-run intermittently fails during Wine's startup: Wine reports could not open working directory and falls back to C:\windows, and the process later exits with status 1 (surfaced by Lutris as Exit with return code 256) with no further error of any kind.

Direct strace evidence (below) shows this is not actually a filesystem problem — the working directory's existence check succeeds immediately before Wine reports it can't be opened. The failure is specific to launching through Lutris; the identical umu-run invocation, run directly from a terminal, has not reproduced this in 5/5 attempts.

This has been reproduced across 3 unrelated games from 3 different installer/repack sources (all Windows-executable installers launched via Lutris's generic "run this .exe" flow, not a scripted Lutris installer), so it does not appear to be specific to any one executable.

Environment

Component Version
umu-launcher 1.4.4
Proton GE-Proton11-6-x86_64
Lutris 0.5.22
Distro Omarchy (Arch-based)
Kernel 7.2.3-arch1-3

STEAM_COMPAT_LIBRARY_PATHS points at a secondary mounted drive (/ssd, a separate partition from $HOME), which is what causes umu/Proton to dynamically assign it an extra DOS drive letter (S: in these reproductions) rather than using one of the drive letters created statically during normal prefix setup (C:, Z:).

Steps to reproduce

  1. Have a Steam/umu compat library path on a separate mounted filesystem from $HOME, so umu/Proton has to dynamically assign it a drive letter (e.g. STEAM_COMPAT_LIBRARY_PATHS=/ssd).
  2. In Lutris, use the generic "run a Windows executable" flow (not a scripted installer) to launch a Windows installer .exe that lives under that secondary drive path.
  3. Retry as needed — this is intermittent, not 100% reproducible on every attempt (see Investigation below).

We were not able to identify a hard trigger for which attempts fail vs. succeed; it looks timing-sensitive.

Expected behavior

The installer launches and its working directory is set to its own containing folder, as passed to umu-run.

Actual behavior

Proton: Error: unable to use parent for game drive, path /ssd
Proton: /path/to/Game/setup.exe
Proton: Executable is a unix path, launching with 'umu.exe'.
wine: could not open working directory L"S:\path\to\Game\", starting in the Windows directory.
Fontconfig error: "/etc/fonts/fonts.conf", line 86: out of memory
Fontconfig error: "/etc/fonts/fonts.conf", line 91: out of memory
Fontconfig error: Cannot load config file from /etc/fonts/fonts.conf
[umu.umu_run] DEBUG: Child <pid> exited with wait status: 1
Initial process has exited (return code: 256)

Investigation

We traced this in detail across several strace -f (and WINEDEBUG=+relay) captures, attached to the live Lutris process before triggering the install, following the whole forked process tree through to the actual failure. Summary of what we ruled out and what we found:

Two messages in the log above are red herrings

  • Proton: Error: unable to use parent for game drive, path /ssd — cosmetic, appears on every launch regardless of success/failure. It's logged whenever the compat library path's last directory component isn't literally named steamapps (true for any non-Steam library). The drive mapping is still created correctly.
  • The Fontconfig error block — confirmed via strace -f -e trace=write to be printed by a different, auxiliary Wine process (C:\windows\system32\explorer.exe /desktop, Wine's desktop-shell helper), not by the process actually running the installer. No corresponding Wine-level error (err: or fixme: channel) was ever observed in the real installer process even with WINEDEBUG=+font,+gdi,+module,+winediag,+process and later WINEDEBUG=-all,+relay active.

The actual failing process and the core finding

The real chain is pv-adverb → proton run setup.exe → wine-preloader → wine "c:\windows\system32\\\umu.exe" "<path>\setup.exe". Tracing that specific process's own syscalls around the moment it prints the working-directory error (WINEDEBUG=-all,+relay, strace -f -tt -s 500 -e trace=%process,%file,write):

05:08:56.689063  newfstatat(AT_FDCWD, ".../pfx/dosdevices/s:/Downloads/X4 - Foundations [FitGirl Repack]/" <unfinished ...>
05:08:56.689098  <... newfstatat resumed>, {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
05:08:56.689675  write(2, "wine: could not open working directory L\"S:\\\\Downloads\\\\X4 - Foundations [FitGirl Repack]\\\\\", starting in the Windows directory.\n", 129)
05:08:56.689731  newfstatat(AT_FDCWD, ".../pfx/dosdevices/c:/windows" <unfinished ...>

The stat()-equivalent check on the working directory succeeds (= 0, valid directory, correct mode/size) 577 microseconds before Wine reports it "could not open" that same directory, with zero other syscalls in between. This directly rules out:

  • The drive-letter symlink not existing yet (confirmed created ~29 seconds earlier, before this Wine process even execve'd)
  • The target directory's bind-mount into the container not being ready (confirmed mounted ~2 seconds before this Wine process started)
  • Any host-level permission/resource error (no EACCES, ENOMEM, EMFILE, etc. anywhere near this — also separately confirmed the host process has 32/65536 file descriptors in use, nowhere near any limit)

Whatever decides "this directory can't be opened" here is happening entirely inside Wine's own path-resolution logic for the dynamically-assigned drive letter — not backed by a failing host syscall at all, so it's invisible to further strace/WINEDEBUG tracing. This looks like a genuine logic bug in how Wine (or umu/Proton's setup of the working-directory argument) resolves a path through a drive letter that was assigned only moments earlier in the same launch, as opposed to one of the drive letters created during normal, static prefix initialization.

Full observed timeline (one failing run)

Time (relative) Event
T+0s Real Wine process (umu.exesetup.exe) execve's. S: drive symlink already exists (created ~4ms before this process started).
T+0.02s First dosdevices/s: check succeeds.
T+0s–29s Silent from this process's perspective (normal first-run Wine startup: DLL/registry init).
T+29s Working-directory check on the specific subdirectory succeeds — then Wine reports failure anyway (577µs later) and falls back to C:\windows. This is non-fatal by itself ("starting in the Windows directory").
T+29s–42s Process continues; several .Xdefaults/.Xdefaults-<host> lookups (ENOENT, expected), a handful of write()s to what's very likely a display-server socket (window/surface setup).
T+42s Successfully stats setup.exe by its absolute path (still resolvable despite the wrong fallback CWD) — confirms the file itself was never the problem.
T+42s + 2ms Clean exit_group(1). No further error of any kind.

The jump from "fell back to the wrong working directory" to "the process exits" is the one link in this chain we could not directly observe (would require debugging inside the Windows-side executable itself, e.g. with winedbg, to see what specifically that installer stub does when it can't find something relative to its own directory) — but every other link is directly evidenced above.

Confirmed specific to Lutris's launch path

The identical reproduction command, run directly in a terminal (env vars copied from Lutris's own debug log) instead of through Lutris's installer UI, has not reproduced this in 5 separate attempts — it completes Wine's startup and proceeds normally every time. We were unable to fully isolate why Lutris's specific process-spawn path makes this more likely to hit (attempts to strace/attach directly to Lutris's own spawn were the source of all the evidence above, but we couldn't get a live syscall trace of Lutris's GTK main process's own scheduling/timing behavior to compare against a bare terminal's). Our best working theory is that it's a timing race sensitive to CPU/IO contention from Lutris's own still-running GUI process during the install — a bare terminal invocation never has to contend with that — but this part remains a hypothesis, not confirmed.

Reproducible test command

For reference, this is the direct (non-Lutris, non-reproducing) invocation used to rule out the workaround path, included here as a known-good baseline to diff against:

bash
env WINEPREFIX=/path/to/prefix \
    GAMEID=umu-default \
    PROTONPATH=/path/to/GE-Proton11-6-x86_64 \
    PROTON_VERB=run \
    UMU_NO_RUNTIME=1 \
    umu-run "/path/to/Game/setup.exe"

Additional notes

  • We're filing this against Lutris because the failure has, so far, only reproduced when launched through Lutris — the identical environment (same WINEPREFIX/PROTONPATH/EXE, copied straight from Lutris's own debug log) run directly via umu-run in a terminal has not reproduced it in 5/5 attempts. That points at something specific to Lutris's own process-spawn path (timing, signal handling, cgroup/systemd scope scheduling while its GUI is still running) as the trigger.
  • That said, the code that actually executes when this fails (Wine's path resolution against a dynamically-assigned drive letter, per the Investigation section above) lives inside the umu-run → Proton → Wine chain that Lutris invokes, not in Lutris's own codebase. So this may ultimately need a fix on the umu-launcher/Proton side once the Lutris-specific trigger is identified — happy to cross-post to umu-launcher's tracker as well if that turns out to be more appropriate, or if someone there recognizes what about Lutris's spawn path could explain the timing difference.
  • Happy to provide the raw strace captures (several hundred MB each) if useful — trimmed the excerpts above for readability.
Full original failure log (click to expand)
lutris-wrapper: /usr/bin/umu-run
Started initial process <pid> from /usr/bin/umu-run "/path/to/Game/setup.exe"
Start monitoring process.
[umu.umu_run] INFO: umu-launcher version 1.4.4
[umu.umu_run] DEBUG: WINEPREFIX=/path/to/prefix
[umu.umu_run] DEBUG: GAMEID=umu-default
[umu.umu_run] DEBUG: PROTONPATH=/path/to/GE-Proton11-6-x86_64
[umu.umu_run] DEBUG: STEAM_COMPAT_LIBRARY_PATHS=/ssd
[umu.umu_run] DEBUG: STEAM_COMPAT_INSTALL_PATH=/path/to/Game
[umu.umu_run] DEBUG: EXE=/path/to/Game/setup.exe
[umu.umu_runtime] INFO: Running 'GE-Proton11-6-x86_64' using runtime 'steamrt4'
ProtonFixes WARN: Skipping fix execution. We are probably running a unit test.
Proton: Error: unable to use parent for game drive, path /ssd
ProtonFixes WARN: Skipping fix execution. We are probably running a unit test.
Proton: Error: unable to use parent for game drive, path /ssd
Proton: /path/to/Game/setup.exe
Proton: Executable is a unix path, launching with 'umu.exe'.
wine: could not open working directory L"S:\path\to\Game\", starting in the Windows directory.
Fontconfig error: "/etc/fonts/fonts.conf", line 86: out of memory
Fontconfig error: "/etc/fonts/fonts.conf", line 91: out of memory
Fontconfig error: Cannot load config file from /etc/fonts/fonts.conf
Fontconfig error: "/etc/fonts/fonts.conf", line 86: out of memory
Fontconfig error: "/etc/fonts/fonts.conf", line 91: out of memory
Fontconfig error: Cannot load config file from /etc/fonts/fonts.conf
Fontconfig error: "/etc/fonts/fonts.conf", line 86: out of memory
Fontconfig error: "/etc/fonts/fonts.conf", line 91: out of memory
Fontconfig error: Cannot load config file from /etc/fonts/fonts.conf
Fontconfig error: "/etc/fonts/fonts.conf", line 86: out of memory
Fontconfig error: "/etc/fonts/fonts.conf", line 91: out of memory
Fontconfig error: Cannot load config file from /etc/fonts/fonts.conf
[umu.umu_run] DEBUG: Child <pid> exited with wait status: 1
Monitored process exited.
Initial process has exited (return code: 256)
All processes have quit
Exit with return code 256
Key strace excerpt: process tree identification (click to expand)
# The real process actually running the installer (not the throwaway bootstrap launch
# that also appears in every log — that one execve's wine with an empty argv and is
# unrelated noise):
execve(".../files/lib/wine/x86_64-unix/wine-preloader",
       [".../wine-preloader", ".../wine", "c:\\windows\\system32\\\\umu.exe",
        "/path/to/Game/setup.exe"], ...)

# S: drive symlink already exists before this process even starts:
symlink("/ssd", ".../pfx/dosdevices/s:")                    # T-4ms relative to execve above

# The directory bind-mount into the container is also already done, ~2s before wine starts:
mount("/oldroot/path/to/Game", "/newroot/path/to/Game", NULL, MS_BIND|MS_REC|MS_SILENT, NULL)

# ~29 seconds of normal Wine first-run startup activity later:
newfstatat(AT_FDCWD, ".../pfx/dosdevices/s:/path/to/Game/", ...) = 0   # SUCCEEDS
write(2, "wine: could not open working directory ...")                 # fails anyway, 577us later

# Process continues for another ~13s, successfully finds setup.exe by absolute path:
newfstatat(AT_FDCWD, ".../pfx/dosdevices/s:/path/to/Game/setup.exe",
           {st_mode=S_IFREG|0644, st_size=6342050, ...}, 0) = 0

# Then exits cleanly with no further error of any kind:
exit_group(1)