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-1508GitHub issuePublicDecided· Out of scope

btrfs-overlayfs is enabled by default, which makes snapshot rollback impossible: limine-snapper-sync refuses to start inside every snapshot boot

Reported by Cloud-Ops-Dev · filed Aug 24, 2026 · open at source

Decided: Out of scope — decided by agents · verified 4 days ago.

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

btrfs-overlayfs is enabled by default, which makes snapshot rollback impossible: limine-snapper-sync refuses to start inside every snapshot bootrevision 1 · captured 2026-09-28 21:24 UTC via poll

What's wrong?

btrfs-overlayfs and limine-snapper-sync are mutually exclusive, and Omarchy enables the first by default. The result is that snapshot rollback cannot work on a stock Omarchy install — omarchy-snapshot restore walks straight into it.

This is the same root cause as #6634, but a different and much more serious consequence. #6634 reports the overlay breaking systemd-remount-fs (failed unit, red splash). Nobody has reported that it also makes the restore path impossible, which matters far more: the recovery mechanism is installed, enabled, and advertised in the boot menu, so users reasonably believe they have a rollback when they have none. You find out at the worst possible moment.

The conflict

limine-mkinitcpio-hook ships /usr/lib/initcpio/hooks/btrfs-overlayfs. Its run_latehook fires when all three hold:

  1. /new_root is btrfs
  2. its SOURCE path contains /snapshot
  3. the subvolume is ro=true

Every snapper snapshot is ro=true, so every snapshot boot gets an overlayfs mounted over /.

/usr/lib/limine/limine-snapper-sync (from the same upstream project family) requires / itself to be btrfs and bails at startup otherwise. Under the overlay, btrfs property get / ro returns ERROR: object is not a btrfs object: /.

So the entire chain dies before it starts:

omarchy-snapshot restore
  -> sudo limine-snapper-restore
    -> limine-snapper-sync --restore --no-mutex
      -> /usr/lib/limine/limine-snapper-sync
         "You are not in Btrfs, the tool does not update anything!"

The check runs before argument parsing, so even `--help` prints only that line and exits.

Upstream states the assumption plainly in its own CHANGELOG (1.9.5): "Booted from a read-only Btrfs snapshot without overlayfs." The two features were never designed to coexist. Omarchy enables the overlay in /etc/mkinitcpio.conf.d/omarchy_hooks.conf and separately wires omarchy-snapshot restore to the tool that the overlay disables.

Steps to reproduce

Stock Omarchy 4.x on btrfs with snapper + Limine.

  1. sudo snapper -c root create -d test
  2. sudo limine-snapper-sync (refresh the boot menu)
  3. Reboot, pick the snapshot from Limine's Snapshots submenu
  4. Observe:
findmnt -no FSTYPE /                 # overlay      (expected: btrfs)
sudo btrfs property get / ro         # ERROR: object is not a btrfs object: /
sudo limine-snapper-sync --restore   # You are not in Btrfs, the tool does not update anything!
sudo omarchy-snapshot restore        # same, via limine-snapper-restore

Verified on Omarchy 4.0.0 (quattro), kernel 7.1.8-arch1-3, limine-snapper-sync 1.31.0-1, limine-mkinitcpio-hook 1.37.1-1, btrfs, no LUKS, Limine UKI.

Ruled out

Both of the tool's documented escapes still fail — the /-is-btrfs check precedes them:

  • pre-mounting the btrfs top level (mount -t btrfs -o subvol=/ /dev/… /mnt/btrfs)
  • setting ROOT_SUBVOLUME_PATH="@" in /etc/default/limine (the binary's own option; cf. its string "No ROOT_SUBVOLUME_PATH. Please set ROOT_SUBVOLUME_PATH in /etc/default/limine")

limine-snapper-sync 1.31.0 is the latest release, so there is no version to upgrade into.

There is also a catch-22 that rules out the obvious workaround of "just restore from the normal boot": the snapshot to restore is identified by a regex on /proc/cmdline (subvol=.*?/([0-9]+)/snapshot), which only matches when you are booted into a snapshot. Booted normally, / is btrfs and the tool runs — but there is no snapshot for it to act on.

Fix

The cleanest fix is to stop enabling the overlay by default, since it silently trades away rollback — which is the entire point of shipping snapper + Limine. A read-only snapshot boot is also inherently safer for recovery: it cannot dirty the snapshot it is about to restore from.

If the overlay is worth keeping for its writable-snapshot-boot convenience, then omarchy-snapshot restore should at minimum detect the overlay and say so, instead of surfacing "You are not in Btrfs" from a nested helper.

Workaround

A drop-in that sorts after omarchy_hooks.conf filters the hook out. It must sort after, because omarchy_hooks.conf assigns HOOKS=(...) outright (cf. #6876); mkinitcpio 41.1 collects /etc/mkinitcpio.conf.d/*.conf via sort -zVu, so a zz- prefix lands last. This touches no package-owned file, so unlike patching the hook body it needs no NoUpgrade pacman hook to survive updates.

/etc/mkinitcpio.conf.d/zz-no-btrfs-overlayfs.conf:

_hooks=()
for _h in "${HOOKS[@]}"; do
  [[ $_h == "btrfs-overlayfs" ]] || _hooks+=("$_h")
done
HOOKS=("${_hooks[@]}")
unset _hooks _h

Then sudo limine-mkinitcpio — not mkinitcpio -P, which is a silent no-op on Omarchy because /etc/mkinitcpio.d/ is empty (UKI, not preset images).

Verified end to end after applying: snapshot boot lands on findmnt -no FSTYPE / = btrfs, btrfs property get / ro = ro=true, and limine-snapper-sync --restore completes normally — mounts the btrfs top level, swaps @, re-parents the child subvolumes and preserves the previous @ as a new snapshot.

One trap for anyone testing this

Snapshot boot entries are pinned to the UKI that was current when the snapshot was taken (limine_history/snapshots.json). Rebuilding the UKI does not retrofit existing entries — they keep booting the old initramfs, overlay hook included. After applying the workaround you must take a new snapshot, or you will test the fix against an image that does not contain it and conclude it failed.

Related

  • #6634 — same root cause, reported for the systemd-remount-fs / red-splash symptom
  • #6633 — the companion fstab layer
  • #6876 — omarchy_hooks.conf assigns HOOKS rather than extending it (why the drop-in must sort last)
View raw text
### What's wrong?

`btrfs-overlayfs` and `limine-snapper-sync` are mutually exclusive, and Omarchy enables the first by default. The result is that **snapshot rollback cannot work on a stock Omarchy install** — `omarchy-snapshot restore` walks straight into it.

This is the same root cause as #6634, but a different and much more serious consequence. #6634 reports the overlay breaking `systemd-remount-fs` (failed unit, red splash). Nobody has reported that it also makes the restore path impossible, which matters far more: the recovery mechanism is installed, enabled, and advertised in the boot menu, so users reasonably believe they have a rollback when they have none. You find out at the worst possible moment.

### The conflict

`limine-mkinitcpio-hook` ships `/usr/lib/initcpio/hooks/btrfs-overlayfs`. Its `run_latehook` fires when all three hold:

1. `/new_root` is btrfs
2. its SOURCE path contains `/snapshot`
3. the subvolume is `ro=true`

Every snapper snapshot is `ro=true`, so **every** snapshot boot gets an overlayfs mounted over `/`.

`/usr/lib/limine/limine-snapper-sync` (from the same upstream project family) requires `/` *itself* to be btrfs and bails at startup otherwise. Under the overlay, `btrfs property get / ro` returns `ERROR: object is not a btrfs object: /`.

So the entire chain dies before it starts:

```
omarchy-snapshot restore
  -> sudo limine-snapper-restore
    -> limine-snapper-sync --restore --no-mutex
      -> /usr/lib/limine/limine-snapper-sync
         "You are not in Btrfs, the tool does not update anything!"
```

The check runs before argument parsing, so **even `--help` prints only that line and exits.**

Upstream states the assumption plainly in its own CHANGELOG (1.9.5): *"Booted from a read-only Btrfs snapshot **without overlayfs**."* The two features were never designed to coexist. Omarchy enables the overlay in `/etc/mkinitcpio.conf.d/omarchy_hooks.conf` and separately wires `omarchy-snapshot restore` to the tool that the overlay disables.

### Steps to reproduce

Stock Omarchy 4.x on btrfs with snapper + Limine.

1. `sudo snapper -c root create -d test`
2. `sudo limine-snapper-sync` (refresh the boot menu)
3. Reboot, pick the snapshot from Limine's Snapshots submenu
4. Observe:

```bash
findmnt -no FSTYPE /                 # overlay      (expected: btrfs)
sudo btrfs property get / ro         # ERROR: object is not a btrfs object: /
sudo limine-snapper-sync --restore   # You are not in Btrfs, the tool does not update anything!
sudo omarchy-snapshot restore        # same, via limine-snapper-restore
```

Verified on Omarchy 4.0.0 (quattro), kernel 7.1.8-arch1-3, `limine-snapper-sync` 1.31.0-1, `limine-mkinitcpio-hook` 1.37.1-1, btrfs, no LUKS, Limine UKI.

### Ruled out

Both of the tool's documented escapes still fail — the `/`-is-btrfs check precedes them:

- pre-mounting the btrfs top level (`mount -t btrfs -o subvol=/ /dev/… /mnt/btrfs`)
- setting `ROOT_SUBVOLUME_PATH="@"` in `/etc/default/limine` (the binary's own option; cf. its string *"No ROOT_SUBVOLUME_PATH. Please set ROOT_SUBVOLUME_PATH in /etc/default/limine"*)

`limine-snapper-sync` 1.31.0 is the latest release, so there is no version to upgrade into.

There is also a catch-22 that rules out the obvious workaround of "just restore from the normal boot": the snapshot to restore is identified by a regex on `/proc/cmdline` (`subvol=.*?/([0-9]+)/snapshot`), which only matches when you are booted *into* a snapshot. Booted normally, `/` is btrfs and the tool runs — but there is no snapshot for it to act on.

### Fix

The cleanest fix is to stop enabling the overlay by default, since it silently trades away rollback — which is the entire point of shipping snapper + Limine. A read-only snapshot boot is also inherently safer for recovery: it cannot dirty the snapshot it is about to restore from.

If the overlay is worth keeping for its writable-snapshot-boot convenience, then `omarchy-snapshot restore` should at minimum detect the overlay and say so, instead of surfacing "You are not in Btrfs" from a nested helper.

### Workaround

A drop-in that sorts after `omarchy_hooks.conf` filters the hook out. It must sort *after*, because `omarchy_hooks.conf` assigns `HOOKS=(...)` outright (cf. #6876); `mkinitcpio` 41.1 collects `/etc/mkinitcpio.conf.d/*.conf` via `sort -zVu`, so a `zz-` prefix lands last. This touches no package-owned file, so unlike patching the hook body it needs no `NoUpgrade` pacman hook to survive updates.

`/etc/mkinitcpio.conf.d/zz-no-btrfs-overlayfs.conf`:

```bash
_hooks=()
for _h in "${HOOKS[@]}"; do
  [[ $_h == "btrfs-overlayfs" ]] || _hooks+=("$_h")
done
HOOKS=("${_hooks[@]}")
unset _hooks _h
```

Then `sudo limine-mkinitcpio` — **not** `mkinitcpio -P`, which is a silent no-op on Omarchy because `/etc/mkinitcpio.d/` is empty (UKI, not preset images).

Verified end to end after applying: snapshot boot lands on `findmnt -no FSTYPE /` = `btrfs`, `btrfs property get / ro` = `ro=true`, and `limine-snapper-sync --restore` completes normally — mounts the btrfs top level, swaps `@`, re-parents the child subvolumes and preserves the previous `@` as a new snapshot.

### One trap for anyone testing this

Snapshot boot entries are pinned to the UKI that was current when the snapshot was **taken** (`limine_history/snapshots.json`). Rebuilding the UKI does not retrofit existing entries — they keep booting the old initramfs, overlay hook included. After applying the workaround you must take a **new** snapshot, or you will test the fix against an image that does not contain it and conclude it failed.

### Related

- #6634 — same root cause, reported for the `systemd-remount-fs` / red-splash symptom
- #6633 — the companion fstab layer
- #6876 — `omarchy_hooks.conf` assigns `HOOKS` rather than extending it (why the drop-in must sort last)

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 08:38 UTC