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.
snapper.sh installs a btrfs snapper config on non-btrfs roots, so snapper-cleanup fails daily
Reported by tpatzelt · filed Aug 10, 2026 · open at source
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?
- AreaOutside the audited area· Decided by agents · verified
- 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?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
System details
Intel i5-10210U, Intel UHD Graphics (CometLake-U GT2), Omarchy 4.0.0 (bb8d2f2), root on ext4
What's wrong?
On a machine whose root filesystem isn't btrfs, install/config/snapper.sh writes a snapper config that claims it is, and then enables the cleanup timer for it. The result is snapper-cleanup.service failing every single day forever.
My root is a plain ext4 partition — no btrfs, no LVM thin pool, no /.snapshots:
$ findmnt / -o TARGET,SOURCE,FSTYPE
TARGET SOURCE FSTYPE
/ /dev/nvme0n1p3 ext4But /etc/snapper/configs/root exists and says otherwise:
# Omarchy snapshots root only for pre-update recovery — kept to 5, no timeline
SUBVOLUME="/"
FSTYPE="btrfs"So the daily timer fires and dies:
× snapper-cleanup.service - Daily Cleanup of Snapper Snapshots
Active: failed (Result: exit-code)
systemd-helper[1148211]: Running number cleanup for 'root'.
systemd-helper[1148211]: IO Error (query default id failed, subvolume is not a btrfs subvolume).
systemd-helper[1148211]: number cleanup for 'root' failed.
systemd[1]: snapper-cleanup.service: Failed with result 'exit-code'.The cause is that the config gets installed unconditionally. In install/config/snapper.sh, create-config correctly fails on ext4 and is swallowed, but the very next line copies the template over the top anyway, and then the timer is enabled regardless:
snapper --no-dbus -c root create-config / >/dev/null 2>&1 || snapper -c root create-config / >/dev/null
fi
install -m 0644 "$template" "$SNAPPER_CONFIG_PATH" # runs even when create-config failed
...
systemctl enable --now snapper-cleanup.timer limine-snapper-sync.service >/dev/null 2>&1 || trueSince default/snapper/root hardcodes FSTYPE="btrfs", every non-btrfs install ends up with a config describing a filesystem it doesn't have. There is no btrfs check anywhere in the script.
There's a second consequence beyond the noisy failed unit. omarchy-snapshot create runs under set -e and loops over whatever snapper list-configs returns:
mapfile -t CONFIGS < <(sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}')
for config in "${CONFIGS[@]}"; do
sudo snapper -c "$config" create -c number -d "$DESC"The phantom root config is in that list, snapper create fails on it, and the script exits non-zero — which is the pre-update snapshot step.
limine-snapper-sync.service also gets enabled on these machines and just announces the same thing on every boot:
limine-snapper-watcher[629]: WARNING: Root filesystem is not Btrfs. limine-snapper-watcher stopped.Suggested fix: guard the whole thing on the actual filesystem, e.g. bail early if findmnt -no FSTYPE / isn't btrfs, and don't enable the timer or limine-snapper-sync.service when there's nothing for them to do.
The local workaround is to remove /etc/snapper/configs/root and disable snapper-cleanup.timer and limine-snapper-sync.service. Nothing is lost by doing so, since no snapshot was ever created on these machines in the first place.
View raw text
### System details
Intel i5-10210U, Intel UHD Graphics (CometLake-U GT2), Omarchy 4.0.0 (bb8d2f2), root on ext4
### What's wrong?
On a machine whose root filesystem isn't btrfs, `install/config/snapper.sh` writes a snapper config that claims it is, and then enables the cleanup timer for it. The result is `snapper-cleanup.service` failing every single day forever.
My root is a plain ext4 partition — no btrfs, no LVM thin pool, no `/.snapshots`:
```
$ findmnt / -o TARGET,SOURCE,FSTYPE
TARGET SOURCE FSTYPE
/ /dev/nvme0n1p3 ext4
```
But `/etc/snapper/configs/root` exists and says otherwise:
```
# Omarchy snapshots root only for pre-update recovery — kept to 5, no timeline
SUBVOLUME="/"
FSTYPE="btrfs"
```
So the daily timer fires and dies:
```
× snapper-cleanup.service - Daily Cleanup of Snapper Snapshots
Active: failed (Result: exit-code)
systemd-helper[1148211]: Running number cleanup for 'root'.
systemd-helper[1148211]: IO Error (query default id failed, subvolume is not a btrfs subvolume).
systemd-helper[1148211]: number cleanup for 'root' failed.
systemd[1]: snapper-cleanup.service: Failed with result 'exit-code'.
```
The cause is that the config gets installed unconditionally. In `install/config/snapper.sh`, `create-config` correctly fails on ext4 and is swallowed, but the very next line copies the template over the top anyway, and then the timer is enabled regardless:
```bash
snapper --no-dbus -c root create-config / >/dev/null 2>&1 || snapper -c root create-config / >/dev/null
fi
install -m 0644 "$template" "$SNAPPER_CONFIG_PATH" # runs even when create-config failed
...
systemctl enable --now snapper-cleanup.timer limine-snapper-sync.service >/dev/null 2>&1 || true
```
Since `default/snapper/root` hardcodes `FSTYPE="btrfs"`, every non-btrfs install ends up with a config describing a filesystem it doesn't have. There is no btrfs check anywhere in the script.
There's a second consequence beyond the noisy failed unit. `omarchy-snapshot create` runs under `set -e` and loops over whatever `snapper list-configs` returns:
```bash
mapfile -t CONFIGS < <(sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}')
for config in "${CONFIGS[@]}"; do
sudo snapper -c "$config" create -c number -d "$DESC"
```
The phantom `root` config is in that list, `snapper create` fails on it, and the script exits non-zero — which is the pre-update snapshot step.
`limine-snapper-sync.service` also gets enabled on these machines and just announces the same thing on every boot:
```
limine-snapper-watcher[629]: WARNING: Root filesystem is not Btrfs. limine-snapper-watcher stopped.
```
Suggested fix: guard the whole thing on the actual filesystem, e.g. bail early if `findmnt -no FSTYPE /` isn't `btrfs`, and don't enable the timer or `limine-snapper-sync.service` when there's nothing for them to do.
The local workaround is to remove `/etc/snapper/configs/root` and disable `snapper-cleanup.timer` and `limine-snapper-sync.service`. Nothing is lost by doing so, since no snapshot was ever created on these machines in the first place.
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.
- Out of scopeDecided by agents · verified · 2026-10-09 04:01 UTC