Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
omarchy-windows-vm: launch fails silently after the first success (setgid re-chmod loop on ~/Windows)
Reported by ZuluPilgrim · filed Sep 12, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #9334 (R-1173). GitHub close reason: completed.
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- Not yet mapped to any requirement or component.
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.
Original report
What happened
After the compose file is migrated to the new root-owned location (/var/lib/omarchy/windows/docker-compose.yml), every subsequent `omarchy-windows-vm launch`/`up`/`up_wait` call keeps re-validating and re-`chmod`ing the legacy shared-folder source directory (`~/Windows`), and that re-validation reliably fails after the first successful launch — with the VM's own critical desktop notification "Failed to start Windows VM" and no diagnostic text printed anywhere (not on the terminal, not in the journal for the launching scope).
Root cause chain, confirmed by tracing with bash -x through pkexec omarchy-windows-vm __priv up_wait:
assert_mounts_safe()unconditionally callsprepare_caller_mounts()on every privileged action whenEUID == 0(i.e. on everyup/up_wait, not just the first-time migration):
if ((EUID == 0)); then
prepare_caller_mounts || return 1
fiprepare_caller_mounts()re-opens the legacy source directories (~/.windows,~/Windows) and requires their mode to read back as exactly700after doingchmod 0700on them:
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ...; return 1; }
storage_mode=$(stat -Lc '%a' ...)
shared_mode=$(stat -Lc '%a' ...)
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
...
return 1
fi This branch has no `echo` on failure — a silent return 1 that bubbles all the way up to "Failed to start Windows VM" with zero explanation.
3. In my case ~/Windows had (and, more importantly, kept getting) a setgid bit (2700 instead of 0700) — something tied to the running VM's live shared-folder passthrough (this directory is bind-mounted through to the dockurr/windows container as /shared for the whole time the VM runs) keeps re-adding the setgid bit shortly after it's cleared.
4. chmod 0700 <path> (a 3-significant-digit numeric mode) does not clear a pre-existing setgid bit — only chmod 2700/chmod g-s/symbolic notation does. So the script's own remediation chmod 0700 call in step 2 is a silent no-op against a directory that already has setgid set, and the mode check keeps failing.
Net effect
- The first launch after migration succeeds (the source dirs happen to be clean at that moment).
- Every launch after that fails, silently, with only a generic "Failed to start Windows VM" notification — because the always-on re-validation in step 1 keeps re-discovering the setgid bit that something (very likely the VM's own SMB/9p sharing of
/sharedwith the Windows guest) keeps restoring. - There is no way for a user to know why it failed short of
bash -x-tracing the privileged helper — none ofomarchy-windows-vm status,launch, or the desktop notification give any hint.
Expected behavior
prepare_caller_mounts's remediation chmod should actually clear pre-existing special bits (e.g.chmod -- 0700numeric mode doesn't do this — usechmod g-s,u-s,-tor an explicit non-abbreviated form, or just retry withchmod 2700 ... && chmod 0700 ...).- More importantly: re-verifying/re-establishing the legacy-source bind mounts on every single launch (even when the compose is already fully migrated and the container/mounts are already up and healthy) seems unnecessary and is what turns a one-off permission quirk into a permanent failure loop. Consider skipping
prepare_caller_mountswhen the expected protected mounts are already active and healthy (mounts_readyalready exists and is checked separately). - At minimum, any failure branch that can end in "Failed to start Windows VM" should surface the actual reason (even just to the journal) instead of a bare
return 1.
Steps to reproduce
- Have an existing Windows VM installed under the older
~/.config/windows/docker-compose.ymllayout with a~/Windowsshared-folder directory that has (or acquires) a setgid bit. - Upgrade Omarchy to a version that migrates the compose to
/var/lib/omarchy/windows/docker-compose.ymland adds theassert_mounts_safe/prepare_caller_mountsre-validation on every launch. - Launch the Windows VM once — it migrates and starts successfully.
- Launch it again while it's still running — it fails with "Failed to start Windows VM" and no further explanation.
chmod g-s ~/Windowsand launch again — succeeds. Wait a few minutes while the VM keeps running, launch a third time — fails again, andstat -c '%a' ~/Windowsshows2700again.
System details
- Omarchy 4.0.3-1
- Hyprland 0.56.2-2
- Docker 29.7.2 / Docker Compose plugin 5.5.1
- CPU: Intel Xeon E5-1660 v4
- GPU: NVIDIA GeForce GTX 1080 Ti (nvidia driver)
~filesystem: btrfs
View raw text
## What happened
After the compose file is migrated to the new root-owned location (`/var/lib/omarchy/windows/docker-compose.yml`), **every subsequent `omarchy-windows-vm launch`/`up`/`up_wait` call keeps re-validating and re-`chmod`ing the legacy shared-folder source directory (`~/Windows`)**, and that re-validation reliably fails after the first successful launch — with the VM's own critical desktop notification "Failed to start Windows VM" and **no diagnostic text printed anywhere** (not on the terminal, not in the journal for the launching scope).
Root cause chain, confirmed by tracing with `bash -x` through `pkexec omarchy-windows-vm __priv up_wait`:
1. `assert_mounts_safe()` unconditionally calls `prepare_caller_mounts()` on every privileged action when `EUID == 0` (i.e. on every `up`/`up_wait`, not just the first-time migration):
```
if ((EUID == 0)); then
prepare_caller_mounts || return 1
fi
```
2. `prepare_caller_mounts()` re-opens the legacy source directories (`~/.windows`, `~/Windows`) and requires their mode to read back as exactly `700` after doing `chmod 0700` on them:
```
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ...; return 1; }
storage_mode=$(stat -Lc '%a' ...)
shared_mode=$(stat -Lc '%a' ...)
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
...
return 1
fi
```
This branch has **no `echo` on failure** — a silent `return 1` that bubbles all the way up to "Failed to start Windows VM" with zero explanation.
3. In my case `~/Windows` had (and, more importantly, *kept getting*) a setgid bit (`2700` instead of `0700`) — something tied to the running VM's live shared-folder passthrough (this directory is bind-mounted through to the dockurr/windows container as `/shared` for the whole time the VM runs) keeps re-adding the setgid bit shortly after it's cleared.
4. `chmod 0700 <path>` (a **3-significant-digit** numeric mode) does **not** clear a pre-existing setgid bit — only `chmod 2700`/`chmod g-s`/symbolic notation does. So the script's own remediation `chmod 0700` call in step 2 is a silent no-op against a directory that already has setgid set, and the mode check keeps failing.
## Net effect
- The **first** launch after migration succeeds (the source dirs happen to be clean at that moment).
- **Every launch after that** fails, silently, with only a generic "Failed to start Windows VM" notification — because the always-on re-validation in step 1 keeps re-discovering the setgid bit that something (very likely the VM's own SMB/9p sharing of `/shared` with the Windows guest) keeps restoring.
- There is no way for a user to know *why* it failed short of `bash -x`-tracing the privileged helper — none of `omarchy-windows-vm status`, `launch`, or the desktop notification give any hint.
## Expected behavior
- `prepare_caller_mounts`'s remediation chmod should actually clear pre-existing special bits (e.g. `chmod -- 0700` numeric mode doesn't do this — use `chmod g-s,u-s,-t` or an explicit non-abbreviated form, or just retry with `chmod 2700 ... && chmod 0700 ...`).
- More importantly: re-verifying/re-establishing the legacy-source bind mounts on *every single launch* (even when the compose is already fully migrated and the container/mounts are already up and healthy) seems unnecessary and is what turns a one-off permission quirk into a permanent failure loop. Consider skipping `prepare_caller_mounts` when the expected protected mounts are already active and healthy (`mounts_ready` already exists and is checked separately).
- At minimum, any failure branch that can end in "Failed to start Windows VM" should surface the actual reason (even just to the journal) instead of a bare `return 1`.
## Steps to reproduce
1. Have an existing Windows VM installed under the older `~/.config/windows/docker-compose.yml` layout with a `~/Windows` shared-folder directory that has (or acquires) a setgid bit.
2. Upgrade Omarchy to a version that migrates the compose to `/var/lib/omarchy/windows/docker-compose.yml` and adds the `assert_mounts_safe`/`prepare_caller_mounts` re-validation on every launch.
3. Launch the Windows VM once — it migrates and starts successfully.
4. Launch it again while it's still running — it fails with "Failed to start Windows VM" and no further explanation.
5. `chmod g-s ~/Windows` and launch again — succeeds. Wait a few minutes while the VM keeps running, launch a third time — fails again, and `stat -c '%a' ~/Windows` shows `2700` again.
## System details
- Omarchy 4.0.3-1
- Hyprland 0.56.2-2
- Docker 29.7.2 / Docker Compose plugin 5.5.1
- CPU: Intel Xeon E5-1660 v4
- GPU: NVIDIA GeForce GTX 1080 Ti (nvidia driver)
- `~` filesystem: btrfs
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
No decision has been recorded yet.