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

Hyprland reload-pause guard silently fails to prevent mid-update Lua reload — emergency mode banner during omarchy update

Reported by tecnarchico · filed Aug 27, 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

Hyprland reload-pause guard silently fails to prevent mid-update Lua reload — emergency mode banner during omarchy updaterevision 1 · captured 2026-09-28 21:24 UTC via poll

What happened

During omarchy update (4.0.0-1 → 4.0.1-1), Hyprland's Lua config reloaded in the middle of the pacman transaction, exactly while pacman was replacing the omarchy-settings files. For a moment /usr/share/omarchy/default/hypr/bootstrap.lua did not exist on disk, so the dofile in ~/.config/hypr/hyprland.lua failed, no binds were registered, and Hyprland 0.56's emergency mode tripped:

Emergency mode tripped: A lua config error resulted in no binds being registered. Emergency binds active: SUPER + Q → any known terminal, SUPER + R → hyprland-run, SUPER + M → Exit
Your config has errors:
cannot open /usr/share/omarchy/default/hypr/bootstrap.lua: No such file or directory
stack traceback:
        [C]: in global 'dofile'

The banner sat on top of every workspace for the rest of the update (screenshot attached).

What I expected

10-omarchy-hyprland-reload-pause.hook exists to prevent exactly this: it runs omarchy-hyprland-reload-guard pause as a PreTransaction hook, which is supposed to set misc.disable_autoreload = true and debug.suppress_errors = true on every running instance so no reload can observe the half-replaced tree.

Timeline (from /var/log/pacman.log and the user journal)

  • 23:51:47 — 10-omarchy-hyprland-reload-pause.hook runs. The guard's state file was created in /run/omarchy/hyprland-reload-guard/ with the correct saved option values, so the script ran and its two getoption reads succeeded.
  • 23:52:04–05 — omarchy-settings and omarchy upgraded (files replaced).
  • 23:52:05 — the user journal shows Hyprland recompiling its keymap (xkbcomp warnings), the fingerprint of a config reload. The emergency banner appeared at this point and referenced the transiently missing bootstrap.lua.

Why I believe the pause silently failed

I verified the guard's mechanism works when invoked as the session user:

  • hyprctl eval 'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })' succeeds and getoption confirms the values.
  • With that pause active, neither touch nor a real rewrite of ~/.config/hypr/hyprland.lua or ~/.config/hypr/bindings.lua triggers a reload. So disable_autoreload does block file-triggered reloads, including for Lua modules.

Yet on the real run the reload fired 17 seconds after the pause hook. The pause path in omarchy-hyprland-reload-guard is:

hyprctl_instance "$runtime_dir" "$signature" eval \
  'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })' \
  >/dev/null 2>&1 || true

Every failure mode of that eval — running as root against the user instance included — is swallowed by >/dev/null 2>&1 || true, so if it is rejected or errors, the "pause" is silently a no-op while the state file still gets written (the state file is created before the eval, from the two successful getoption reads). That matches the observed behavior exactly: state file present, options not actually set, reload not prevented.

Suggestion

After the pause eval, read the option back and verify it is actually true; log loudly (the hook output surfaces in the pacman transcript) when it is not. The resume path has the same silent-failure shape and would benefit from the same check.

System

  • Omarchy 4.0.1-1, hyprland 0.56.2-1 (Arch package)
  • CPU: Intel Core i7-14650HX
  • GPU: Intel Raptor Lake-S UHD + NVIDIA RTX 4080 Max-Q (hybrid), nvidia-dkms 610.57.04
  • Kernel: 7.1.8-arch1-3 → 7.1.9-arch1-2 during the affected update
View raw text
## What happened

During `omarchy update` (4.0.0-1 → 4.0.1-1), Hyprland's Lua config reloaded in the middle of the pacman transaction, exactly while pacman was replacing the `omarchy-settings` files. For a moment `/usr/share/omarchy/default/hypr/bootstrap.lua` did not exist on disk, so the `dofile` in `~/.config/hypr/hyprland.lua` failed, no binds were registered, and Hyprland 0.56's emergency mode tripped:

```
Emergency mode tripped: A lua config error resulted in no binds being registered. Emergency binds active: SUPER + Q → any known terminal, SUPER + R → hyprland-run, SUPER + M → Exit
Your config has errors:
cannot open /usr/share/omarchy/default/hypr/bootstrap.lua: No such file or directory
stack traceback:
        [C]: in global 'dofile'
```

The banner sat on top of every workspace for the rest of the update (screenshot attached).

## What I expected

`10-omarchy-hyprland-reload-pause.hook` exists to prevent exactly this: it runs `omarchy-hyprland-reload-guard pause` as a PreTransaction hook, which is supposed to set `misc.disable_autoreload = true` and `debug.suppress_errors = true` on every running instance so no reload can observe the half-replaced tree.

## Timeline (from `/var/log/pacman.log` and the user journal)

- `23:51:47` — `10-omarchy-hyprland-reload-pause.hook` runs. The guard's state file was created in `/run/omarchy/hyprland-reload-guard/` with the correct saved option values, so the script ran and its two `getoption` reads succeeded.
- `23:52:04–05` — `omarchy-settings` and `omarchy` upgraded (files replaced).
- `23:52:05` — the user journal shows Hyprland recompiling its keymap (xkbcomp warnings), the fingerprint of a config reload. The emergency banner appeared at this point and referenced the transiently missing `bootstrap.lua`.

## Why I believe the pause silently failed

I verified the guard's mechanism works when invoked as the session user:

- `hyprctl eval 'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })'` succeeds and `getoption` confirms the values.
- With that pause active, neither `touch` nor a real rewrite of `~/.config/hypr/hyprland.lua` or `~/.config/hypr/bindings.lua` triggers a reload. So `disable_autoreload` does block file-triggered reloads, including for Lua modules.

Yet on the real run the reload fired 17 seconds after the pause hook. The pause path in `omarchy-hyprland-reload-guard` is:

```bash
hyprctl_instance "$runtime_dir" "$signature" eval \
  'hl.config({ misc = { disable_autoreload = true }, debug = { suppress_errors = true } })' \
  >/dev/null 2>&1 || true
```

Every failure mode of that `eval` — running as root against the user instance included — is swallowed by `>/dev/null 2>&1 || true`, so if it is rejected or errors, the "pause" is silently a no-op while the state file still gets written (the state file is created *before* the eval, from the two successful `getoption` reads). That matches the observed behavior exactly: state file present, options not actually set, reload not prevented.

## Suggestion

After the pause eval, read the option back and verify it is actually `true`; log loudly (the hook output surfaces in the pacman transcript) when it is not. The resume path has the same silent-failure shape and would benefit from the same check.

## System

- Omarchy 4.0.1-1, hyprland 0.56.2-1 (Arch package)
- CPU: Intel Core i7-14650HX
- GPU: Intel Raptor Lake-S UHD + NVIDIA RTX 4080 Max-Q (hybrid), nvidia-dkms 610.57.04
- Kernel: 7.1.8-arch1-3 → 7.1.9-arch1-2 during the affected update

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