Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-5070GitHub issuePublicReceived

omarchy-windows-vm remove/launch silently fails when ~/Windows has a setgid bit (chmod numeric mode can't clear it)

Reported by NeverSoberKG · filed Sep 13, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #9334 (R-1173). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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

omarchy-windows-vm remove/launch silently fails when ~/Windows has a setgid bit (chmod numeric mode can't clear it)revision 1 · captured 2026-10-04 12:10 UTC via poll

Summary

omarchy-windows-vm remove (and launch/install, which share the same code path) can fail with a generic, unhelpful error if ~/Windows or ~/.windows ever picks up the setgid bit — which the dockurr/windows container itself can set (e.g. via its internal Samba share setup). No VM data is lost when this happens, but the tool gives no indication of what actually went wrong.

Observed behavior

Running omarchy-windows-vm remove prints:

Removing Windows VM...
❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying.

with no further detail, and exits 1. This happens consistently on retry, and also affects launch/up, which routes through the same prepare_caller_mounts helper.

Root cause

In prepare_caller_mounts() (bin/omarchy-windows-vm), the script does:

chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ... }
storage_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$storage_fd" 2>/dev/null) || storage_mode=""
shared_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$shared_fd" 2>/dev/null) || shared_mode=""
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
  exec {storage_fd}<&-
  exec {shared_fd}<&-
  return 1
fi

GNU coreutils chmod, when given a numeric mode (including 4-digit forms like 0700), intentionally preserves an existing setgid bit on a directory — this is documented upstream behavior, not a bug in chmod:

$ stat -c '%a' ~/Windows
2700
$ chmod -v 0700 ~/Windows
mode of '/home/user/Windows' retained as 2700 (rwx--S---)
$ stat -c '%a' ~/Windows
2700
$ chmod -v g-s ~/Windows
mode of '/home/user/Windows' changed from 2700 (rwx--S---) to 0700 (rwx------)

Only a symbolic mode change (g-s, or chmod --reference, etc.) actually clears the bit; the numeric chmod 0700 used in the script is silently a no-op on the special bits whenever they're already set on a directory. (chmod --version: GNU coreutils 9.11.)

Since chmod 0700 "succeeds" (exit 0) without actually reaching the intended mode, the subsequent [[ $shared_mode != 700 ]] check fails, prepare_caller_mounts returns 1, and every caller (assert_mounts_safe → __priv_up / __priv_remove) aborts. None of these failure branches print a message for this specific case, so the user only ever sees the generic wrapper error in remove_windows():

priv remove || {
  echo "❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying." >&2
  exit 1
}

No data is touched or lost — the abort happens before dc down/deletion — but the error message gives no actionable information, and the underlying condition doesn't self-heal (every retry fails identically).

How the setgid bit got set in the first place

I didn't chase this fully, but ~/Windows is the folder bind-mounted into the dockurr/windows container as /shared, which that image commonly exposes over Samba. Samba setups often set the setgid bit on shared directories for consistent group ownership of new files, which would explain a host-side directory ending up setgid without the user (or omarchy) ever setting it directly.

Suggested fix

In prepare_caller_mounts(), clear the special bits explicitly instead of relying on a numeric mode, e.g.:

chmod u=rwx,go=,g-s,u-s -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ... }

or equivalently or chmod -s in addition to the numeric mode. Additionally/alternatively, it'd help to have assert_mounts_safe/prepare_caller_mounts failures each print a specific echo ... >&2 reason (several current failure branches, including this one, return 1 silently), so a future edge case doesn't again produce only the generic "stopped before user-side cleanup" message with no diagnostic trail.

Reproduction

mkdir -p ~/Windows
chmod 2700 ~/Windows   # simulate what the container did
omarchy-windows-vm remove   # (with an existing Windows VM installed)
# -> "Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying."

Environment

  • Omarchy on Arch Linux, Hyprland/uwsm session
  • chmod (GNU coreutils) 9.11
  • ~/Windows on btrfs (/home subvolume), not a separate mount
  • Docker Compose v2 (docker-compose symlinked to the compose v2 CLI plugin)
View raw text
## Summary

`omarchy-windows-vm remove` (and `launch`/`install`, which share the same code path) can fail with a generic, unhelpful error if `~/Windows` or `~/.windows` ever picks up the setgid bit — which the `dockurr/windows` container itself can set (e.g. via its internal Samba share setup). No VM data is lost when this happens, but the tool gives no indication of what actually went wrong.

## Observed behavior

Running `omarchy-windows-vm remove` prints:

```
Removing Windows VM...
❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying.
```

with no further detail, and exits 1. This happens consistently on retry, and also affects `launch`/`up`, which routes through the same `prepare_caller_mounts` helper.

## Root cause

In `prepare_caller_mounts()` (bin/omarchy-windows-vm), the script does:

```bash
chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ... }
storage_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$storage_fd" 2>/dev/null) || storage_mode=""
shared_mode=$(stat -Lc '%a' "/proc/$BASHPID/fd/$shared_fd" 2>/dev/null) || shared_mode=""
if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then
  exec {storage_fd}<&-
  exec {shared_fd}<&-
  return 1
fi
```

GNU coreutils `chmod`, when given a **numeric** mode (including 4-digit forms like `0700`), intentionally **preserves an existing setgid bit on a directory** — this is documented upstream behavior, not a bug in chmod:

```
$ stat -c '%a' ~/Windows
2700
$ chmod -v 0700 ~/Windows
mode of '/home/user/Windows' retained as 2700 (rwx--S---)
$ stat -c '%a' ~/Windows
2700
$ chmod -v g-s ~/Windows
mode of '/home/user/Windows' changed from 2700 (rwx--S---) to 0700 (rwx------)
```

Only a symbolic mode change (`g-s`, or `chmod --reference`, etc.) actually clears the bit; the numeric `chmod 0700` used in the script is silently a no-op on the special bits whenever they're already set on a directory. (`chmod --version`: GNU coreutils 9.11.)

Since `chmod 0700` "succeeds" (exit 0) without actually reaching the intended mode, the subsequent `[[ $shared_mode != 700 ]]` check fails, `prepare_caller_mounts` returns 1, and every caller (`assert_mounts_safe` → `__priv_up` / `__priv_remove`) aborts. None of these failure branches print a message for this specific case, so the user only ever sees the generic wrapper error in `remove_windows()`:

```bash
priv remove || {
  echo "❌ Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying." >&2
  exit 1
}
```

No data is touched or lost — the abort happens before `dc down`/deletion — but the error message gives no actionable information, and the underlying condition doesn't self-heal (every retry fails identically).

### How the setgid bit got set in the first place

I didn't chase this fully, but `~/Windows` is the folder bind-mounted into the `dockurr/windows` container as `/shared`, which that image commonly exposes over Samba. Samba setups often set the setgid bit on shared directories for consistent group ownership of new files, which would explain a host-side directory ending up setgid without the user (or omarchy) ever setting it directly.

## Suggested fix

In `prepare_caller_mounts()`, clear the special bits explicitly instead of relying on a numeric mode, e.g.:

```bash
chmod u=rwx,go=,g-s,u-s -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ... }
```

or equivalently or `chmod -s` in addition to the numeric mode. Additionally/alternatively, it'd help to have `assert_mounts_safe`/`prepare_caller_mounts` failures each print a specific `echo ... >&2` reason (several current failure branches, including this one, return 1 silently), so a future edge case doesn't again produce only the generic "stopped before user-side cleanup" message with no diagnostic trail.

## Reproduction

```bash
mkdir -p ~/Windows
chmod 2700 ~/Windows   # simulate what the container did
omarchy-windows-vm remove   # (with an existing Windows VM installed)
# -> "Windows VM removal stopped before user-side cleanup; inspect the VM data before retrying."
```

## Environment

- Omarchy on Arch Linux, Hyprland/uwsm session
- `chmod (GNU coreutils) 9.11`
- `~/Windows` on btrfs (`/home` subvolume), not a separate mount
- Docker Compose v2 (`docker-compose` symlinked to the compose v2 CLI plugin)

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.