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.
Super + K hangs and spawns CPU-bound Lua processes when config iterates hl.get_workspaces()
Reported by jermartinz · filed Oct 1, 2026Closed upstream on 2026-10-13 by the bot omarchybot, as a duplicate (target not recorded).
R-1816 is the earliest report of this defect — filed Aug 15, 2026, open upstream. This report (filed Oct 1, 2026) describes the same defect, so it is folded under it in the inbox.
Decided by agents · verified· Oct 8, 2026
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?
- 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
- Omarchy:
4.0.4-1 - Hyprland:
0.56.2-2 - Lua:
5.5.1-1 - Kernel:
7.2.5-3-omarchy(x86_64) - CPU: AMD Ryzen 5 5600X (6 cores / 12 threads)
- GPU: NVIDIA GeForce RTX 3060
What's wrong?
Opening the keybindings menu with Super + K hangs while scanning a custom Lua Hyprland configuration containing a top-level ipairs(hl.get_workspaces()) loop. Each invocation leaves a Lua process consuming approximately 100% of one CPU core. Four concurrent processes were observed at 98–99% CPU each, with only about 3 MB RSS per process.
The configuration uses this loop to apply workspace-to-monitor rules to existing workspaces. The failure occurs in the menu's standalone Lua scanner, rather than in the compositor's execution of the configuration.
Steps to reproduce
- In a Lua-based Hyprland configuration, add a top-level iteration over workspaces. This minimal loop is enough to exercise the scanner problem:
for _, ws in ipairs(hl.get_workspaces()) do
-- Even an empty body never terminates under the menu's mock.
end- Trigger a cache miss and run the menu. To test without changing the normal cache or leaving another runaway process, use a temporary cache and a bounded command:
task_cache_dir=$(mktemp -d)
XDG_CACHE_HOME="$task_cache_dir" timeout 5s omarchy menu keybindings --print- The command emits no keybindings and times out with exit status
124. On a cache miss, pressing Super + K without a timeout leaves the scanner spinning; repeated attempts accumulate CPU-bound Lua processes.
Expected: The keybindings scan terminates and the menu opens. Runtime workspace queries should not cause an unbounded scan.
Actual: The scanner loops indefinitely and the menu cannot finish building its cache.
Confirmed cause
In build_lua_bind_cache(), the scanner executes the user's configuration with pcall(dofile, config), using a mocked hl API. Unimplemented methods resolve to the noop table. Its __call returns that same table, and its __index returns that same table for every key:
local noop
noop = setmetatable({}, {
__index = function()
return noop
end,
__call = function()
return noop
end,
})Consequently, hl.get_workspaces() returns noop; ipairs keeps indexing positive integers, receiving a non-nil value forever. pcall does not help because no error is raised.
The same mock is present in the official source checked at commit `c05d90196fc0dd5c21e2e797d80ffcc60d5e39fa`. The runtime reproduction below was performed with the installed 4.0.4-1 script.
Diagnostic evidence and candidate fix
An instruction-limited copy of the extracted scanner aborts with a traceback pointing to the top-level workspace loop in the user's hyprland.lua:
SCAN INSTRUCTION LIMIT
stack traceback:
...diagnostic.lua:5: in hook '?'
.../hyprland.lua:63: in main chunk
[C]: in function 'dofile'
[C]: in global 'pcall'
...diagnostic.lua:158: in main chunkAdding an explicit stub to the mocked hl table fixes this specific reproduction:
get_workspaces = function()
return {}
end,Verified using the full menu script, a temporary cache, and a five-second timeout:
Original installed script: exit 124, 0 output lines
Patched temporary copy: exit 0, 224 output linesThe patched extracted Lua scanner also terminates successfully and emits 223 binding records. No installed scripts or user configuration were modified for these tests.
An explicit empty collection stub addresses get_workspaces(). A time or instruction budget around configuration scanning would additionally prevent other custom configuration code from leaving unbounded CPU-bound scanners.
View raw text
### System details
- Omarchy: `4.0.4-1`
- Hyprland: `0.56.2-2`
- Lua: `5.5.1-1`
- Kernel: `7.2.5-3-omarchy` (x86_64)
- CPU: AMD Ryzen 5 5600X (6 cores / 12 threads)
- GPU: NVIDIA GeForce RTX 3060
### What's wrong?
Opening the keybindings menu with **Super + K** hangs while scanning a custom Lua Hyprland configuration containing a top-level `ipairs(hl.get_workspaces())` loop. Each invocation leaves a Lua process consuming approximately 100% of one CPU core. Four concurrent processes were observed at 98–99% CPU each, with only about 3 MB RSS per process.
The configuration uses this loop to apply workspace-to-monitor rules to existing workspaces. The failure occurs in the menu's standalone Lua scanner, rather than in the compositor's execution of the configuration.
### Steps to reproduce
1. In a Lua-based Hyprland configuration, add a top-level iteration over workspaces. This minimal loop is enough to exercise the scanner problem:
```lua
for _, ws in ipairs(hl.get_workspaces()) do
-- Even an empty body never terminates under the menu's mock.
end
```
2. Trigger a cache miss and run the menu. To test without changing the normal cache or leaving another runaway process, use a temporary cache and a bounded command:
```bash
task_cache_dir=$(mktemp -d)
XDG_CACHE_HOME="$task_cache_dir" timeout 5s omarchy menu keybindings --print
```
3. The command emits no keybindings and times out with exit status `124`. On a cache miss, pressing Super + K without a timeout leaves the scanner spinning; repeated attempts accumulate CPU-bound Lua processes.
**Expected:** The keybindings scan terminates and the menu opens. Runtime workspace queries should not cause an unbounded scan.
**Actual:** The scanner loops indefinitely and the menu cannot finish building its cache.
### Confirmed cause
In `build_lua_bind_cache()`, the scanner executes the user's configuration with `pcall(dofile, config)`, using a mocked `hl` API. Unimplemented methods resolve to the `noop` table. Its `__call` returns that same table, and its `__index` returns that same table for every key:
```lua
local noop
noop = setmetatable({}, {
__index = function()
return noop
end,
__call = function()
return noop
end,
})
```
Consequently, `hl.get_workspaces()` returns `noop`; `ipairs` keeps indexing positive integers, receiving a non-nil value forever. `pcall` does not help because no error is raised.
The same mock is present in the official source checked at commit [`c05d90196fc0dd5c21e2e797d80ffcc60d5e39fa`](https://github.com/basecamp/omarchy/blob/c05d90196fc0dd5c21e2e797d80ffcc60d5e39fa/bin/omarchy-menu-keybindings#L187-L230). The runtime reproduction below was performed with the installed `4.0.4-1` script.
### Diagnostic evidence and candidate fix
An instruction-limited copy of the extracted scanner aborts with a traceback pointing to the top-level workspace loop in the user's `hyprland.lua`:
```text
SCAN INSTRUCTION LIMIT
stack traceback:
...diagnostic.lua:5: in hook '?'
.../hyprland.lua:63: in main chunk
[C]: in function 'dofile'
[C]: in global 'pcall'
...diagnostic.lua:158: in main chunk
```
Adding an explicit stub to the mocked `hl` table fixes this specific reproduction:
```lua
get_workspaces = function()
return {}
end,
```
Verified using the full menu script, a temporary cache, and a five-second timeout:
```text
Original installed script: exit 124, 0 output lines
Patched temporary copy: exit 0, 224 output lines
```
The patched extracted Lua scanner also terminates successfully and emits 223 binding records. No installed scripts or user configuration were modified for these tests.
An explicit empty collection stub addresses `get_workspaces()`. A time or instruction budget around configuration scanning would additionally prevent other custom configuration code from leaving unbounded CPU-bound scanners.
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
- Fixed bypr/14128· confirmed
- Fixed bypr/12712· confirmed
- Related PRpr/12916· confirmed
- Duplicate ofR-1816omarchy-menu-keybindings hangs forever when a user Lua config iterates hl.get_monitors()· decided by agents · verified
- Fixed bypr/7564· confirmed
- Fixed bypr/11733· confirmed
- Fixed bypr/12155· confirmed
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.