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.
omarchy-capture-screenshot kills the compositor: `hyprctl eval` of cursor:no_hardware_cursors faults in hl.config() (SIGABRT)
Reported by jeffsidekick · filed Aug 28, 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 happens
Pressing PRINT terminates the entire Hyprland session with SIGABRT. No screenshot
is taken — the compositor dies before capture begins, taking every open window
with it. Reproduces every time.
Expected
A screenshot.
Cause
omarchy-capture-screenshot line 45 runs, as the first thing it does
(set_no_hw_cursors 0, before omarchy-capture-region):
set_no_hw_cursors() {
hyprctl eval "hl.config({ cursor = { no_hardware_cursors = $1 } })" &>/dev/null ||
hyprctl keyword cursor:no_hardware_cursors "$1" &>/dev/null
}That eval faults inside Hyprland's hl.config() handling. Symbolized stack
(debuginfod, coredumpctl PID 948951):
#2 abort
#3 Hyprland + 0x3bc7f4 <- Hyprland's crash handler
#4 <signal handler called>
#5 Hyprland + 0x44de96 <- faults here, called from Lua
... liblua ...
#18 Config::Lua::CConfigManager::guardedPCall(int, int, int, int, string_view)
... liblua ...
#26 Config::Lua::CConfigManager::guardedPCall(...)
#27 Config::Lua::CConfigManager::eval(std::string const&, bool)
#29 std::_Function_handler<...eHyprCtlOutputFormat...>::_M_invoke
#30 CHyprCtl::getReply(std::string)
#32 wl_event_loop_dispatch
#33 wl_display_run
#34 CEventLoopManager::enterLoop()
#35 mainSo: a memory fault inside the hl.config() path, surfacing as SIGABRT via
Hyprland's own crash handler, while servicing the hyprctl IPC request.
The xdg-desktop-portal-hyprland SIGSEGV and hyprland-dialog SIGABRT that
appear in the same second are consequences, not causes — the portal's stack is
inside exit, crashing on wayland teardown after the compositor vanished.
Two secondary problems in the same three lines
- The
|| hyprctl keyword ...fallback can never run. It only fires ifeval
returns failure, but here eval takes the compositor down instead of
returning at all.
2. hyprctl keyword is a no-op on this Hyprland build regardless — it prints
keyword can't work with non-legacy parsers. Use eval. and still exits 0.
(Same underlying behaviour as #7961.)
Not a local-config problem
Reverted ~/.config/hypr/{monitors,bindings,autostart}.lua to the shipped
defaults and reloaded — still crashes, identical stack (PID 996562). The user's
config is not involved.
Reproduce
- Omarchy 4.0.1-1, Hyprland 0.56.2, AMD iGPU.
- Press PRINT.
- Session dies.
coredumpctl listshows Hyprland SIGABRT.
Note on the toggle itself
On this machine the toggle is a no-op in intent: cursor:no_hardware_cursors is
unset (default 2) and the output reports hardwareCursorsInUse: true. Hardware
cursors are already in use, so the setting the script is forcing is the one
already in effect — and it still crashes.
Related
#8240 concerns the same three lines — the picker running with hardware cursors
forced on, hiding the pointer on nouveau/vmwgfx — but reports no crash. Same
call site, different failure; both would be resolved by not forcing the setting
during selection, or by not using hl.config() for it.
Workaround
Route PRINT through a wrapper that runs the real script with a shimmed hyprctl
which drops that one eval and execs the real binary for everything else.
(/usr/share/omarchy/bin is first in the session PATH, so the script itself
cannot be shadowed from /usr/local/bin.)
System
- Omarchy 4.0.1-1, Hyprland 0.56.2 (efb5099)
- Kernel 7.1.9-arch1-2
- Beelink SER8, AMD Ryzen 7 8745HS w/ Radeon 780M (amdgpu)
- Display: Samsung Odyssey G95NC, 7680x2160@120 over DP 1.4 + DSC
Filed by Claude Opus 5 (1M context) via Claude Code.
View raw text
## What happens
Pressing PRINT terminates the entire Hyprland session with SIGABRT. No screenshot
is taken — the compositor dies before capture begins, taking every open window
with it. Reproduces every time.
## Expected
A screenshot.
## Cause
`omarchy-capture-screenshot` line 45 runs, as the first thing it does
(`set_no_hw_cursors 0`, before `omarchy-capture-region`):
```bash
set_no_hw_cursors() {
hyprctl eval "hl.config({ cursor = { no_hardware_cursors = $1 } })" &>/dev/null ||
hyprctl keyword cursor:no_hardware_cursors "$1" &>/dev/null
}
```
That `eval` faults inside Hyprland's `hl.config()` handling. Symbolized stack
(debuginfod, `coredumpctl` PID 948951):
```
#2 abort
#3 Hyprland + 0x3bc7f4 <- Hyprland's crash handler
#4 <signal handler called>
#5 Hyprland + 0x44de96 <- faults here, called from Lua
... liblua ...
#18 Config::Lua::CConfigManager::guardedPCall(int, int, int, int, string_view)
... liblua ...
#26 Config::Lua::CConfigManager::guardedPCall(...)
#27 Config::Lua::CConfigManager::eval(std::string const&, bool)
#29 std::_Function_handler<...eHyprCtlOutputFormat...>::_M_invoke
#30 CHyprCtl::getReply(std::string)
#32 wl_event_loop_dispatch
#33 wl_display_run
#34 CEventLoopManager::enterLoop()
#35 main
```
So: a memory fault inside the `hl.config()` path, surfacing as SIGABRT via
Hyprland's own crash handler, while servicing the hyprctl IPC request.
The `xdg-desktop-portal-hyprland` SIGSEGV and `hyprland-dialog` SIGABRT that
appear in the same second are consequences, not causes — the portal's stack is
inside `exit`, crashing on wayland teardown after the compositor vanished.
## Two secondary problems in the same three lines
1. The `|| hyprctl keyword ...` fallback can never run. It only fires if `eval`
*returns* failure, but here `eval` takes the compositor down instead of
returning at all.
2. `hyprctl keyword` is a no-op on this Hyprland build regardless — it prints
`keyword can't work with non-legacy parsers. Use eval.` and still exits 0.
(Same underlying behaviour as #7961.)
## Not a local-config problem
Reverted `~/.config/hypr/{monitors,bindings,autostart}.lua` to the shipped
defaults and reloaded — still crashes, identical stack (PID 996562). The user's
config is not involved.
## Reproduce
1. Omarchy 4.0.1-1, Hyprland 0.56.2, AMD iGPU.
2. Press PRINT.
3. Session dies. `coredumpctl list` shows Hyprland SIGABRT.
## Note on the toggle itself
On this machine the toggle is a no-op in intent: `cursor:no_hardware_cursors` is
unset (default 2) and the output reports `hardwareCursorsInUse: true`. Hardware
cursors are already in use, so the setting the script is forcing is the one
already in effect — and it still crashes.
## Related
#8240 concerns the same three lines — the picker running with hardware cursors
forced on, hiding the pointer on nouveau/vmwgfx — but reports no crash. Same
call site, different failure; both would be resolved by not forcing the setting
during selection, or by not using `hl.config()` for it.
## Workaround
Route PRINT through a wrapper that runs the real script with a shimmed `hyprctl`
which drops that one `eval` and `exec`s the real binary for everything else.
(`/usr/share/omarchy/bin` is first in the session PATH, so the script itself
cannot be shadowed from `/usr/local/bin`.)
## System
- Omarchy 4.0.1-1, Hyprland 0.56.2 (efb5099)
- Kernel 7.1.9-arch1-2
- Beelink SER8, AMD Ryzen 7 8745HS w/ Radeon 780M (amdgpu)
- Display: Samsung Odyssey G95NC, 7680x2160@120 over DP 1.4 + DSC
---
Filed by Claude Opus 5 (1M context) via Claude Code.
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:47 UTC