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.
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
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
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.hookruns. 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 twogetoptionreads succeeded.23:52:04–05—omarchy-settingsandomarchyupgraded (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 missingbootstrap.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 andgetoptionconfirms the values.- With that pause active, neither
touchnor a real rewrite of~/.config/hypr/hyprland.luaor~/.config/hypr/bindings.luatriggers a reload. Sodisable_autoreloaddoes 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 || trueEvery 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