Repository navigation
Keybindings menu (SUPER+K) hangs forever if hyprland.lua iterates a hyprlua getter #12052
Description
What happened
Any user hyprland.lua that iterates a hyprlua getter — e.g. ipairs(hl.get_windows()) — permanently and silently breaks the keybindings menu (SUPER + K). The menu never opens, nothing is logged, and hyprctl configerrors stays clean, so there is no trail back to the offending config.
Why
omarchy-menu-keybindings re-executes ~/.config/hypr/hyprland.lua under a stub hl in build_lua_bind_cache(), to recover descriptions for binds that Hyprland still reports as dispatcher __lua. The stub's fallback object is:
local noop
noop = setmetatable({}, {
__index = function() return noop end,
__call = function() return noop end,
})hl's own metatable returns this noop for every member it does not explicitly define, so hl.get_windows() returns noop. Since __index answers every key with a non-nil value, ipairs(noop) never reaches a nil and loops forever:
$ lua -e 'local n; n = setmetatable({}, {__index=function() return n end})
local i=0; for _ in ipairs(n) do i=i+1; if i>1000000 then break end end
print(i)'
1000001This affects every unstubbed getter — get_windows, get_workspaces, get_workspace_windows, get_monitors, etc.
Reproduction
mkdir -p /tmp/fakehome/.config/hypr
cat > /tmp/fakehome/.config/hypr/hyprland.lua <<'LUA'
for _, w in ipairs(hl.get_windows() or {}) do print(w.title) end
LUA
timeout 20 env HOME=/tmp/fakehome omarchy-menu-keybindings --print; echo "exit=$?"Result: exit=124 (hung). Remove the loop from that config and the same command returns in 0.011s. Pressing SUPER + K on a real config containing such a loop reproduces it identically.
Impact
- Permanent, not transient. The scan hangs before writing
~/.cache/omarchy/keybindings-*.records, so no cache is ever produced to fall back on.SUPER + Kstays broken until the config is found and edited — and the failure gives no hint which file is responsible. - Each press leaks a spinning process. Every
SUPER + Kleaves twoomarchy-menu-keybindingsbash processes plus aluachild pegged at 100% CPU. I had five stuck instances and two runawayluaprocesses before noticing; load average was 3.84 on an idle desktop. - The
luachild outlives its parent.pkill -f omarchy-menu-keybindingsreaps the bash processes but orphans thelua, which keeps spinning and must be killed by PID. - Because the processes are children of the shell service, the CPU burn is attributed to
omarchy-shell.service, which points diagnosis away from the real cause.
Suggested fix
Either of these alone closes the loop; together they also bound the damage from anything else the stub cannot anticipate.
- Terminate
ipairson the stub — have__indexreturnnilfor positive integer keys, so an array iteration yields zero items instead of running forever. - Return real empty arrays for the known getters — stub
get_windows,get_workspaces,get_workspace_windowsandget_monitorsasfunction() return {} end, which is also what a correct scan wants. - Bound the scan — wrap the
luaheredoc intimeoutso a pathological config degrades to "descriptions missing" rather than "menu never opens and a core spins".
A timeout alone would have turned this from a silent permanent breakage into a visibly degraded menu, which is a much easier bug to report.
Discovered via
A third-party Hyprland Lua overlay (window-placement rules for a game companion app) sourced from the tail of hyprland.lua. Fixed on that side by guarding the iteration with rawget(value, 1) == nil, which bypasses the stub's __index while leaving real hyprlua arrays untouched — but any config doing the obvious thing hits this.
System
| Omarchy | 4.0.3-1 |
| Hyprland | 0.56.2 (commit efb5099) |
| CPU | Intel Core 5 210H |
| GPU | Intel Raptor Lake-P iGPU + NVIDIA RTX 4050 Max-Q |
| Kernel | Linux 7.2.3-arch1-3 |
(omarchy debug is referenced in the docs but is not a command in 4.0.3, so the above is collected by hand.)
Activity
omarchybot commentedon Oct 12, 2026
This is the same bug as #7025, which was reported earlier and is still open:
build_lua_bind_cache()inbin/omarchy-menu-keybindingsrunshyprland.luaunder a stubhlwhosenoopfallback answers every key with itself (lines 209–217 on currentquattro, 9480d1b), soipairsover any getter's result never reachesnil. #7025 describes it withhl.get_monitors()and its thread confirmshl.get_windows()too; here it ishl.get_windows(). Same cause, same fix, so I'm closing this one as a duplicate to keep the discussion in one place. If you think they differ, reopen it with a note on what is different.Your write-up adds things #7025 can use: the hang happens before
keybindings-*.recordsis written, so no cache is left to fall back on; each press leaves aluachild spinning thatpkill -f omarchy-menu-keybindingsdoes not reap; andrawget(value, 1) == nilworks as a guard on the config side until a fix lands. The open fixes are discussed on #7025: #7564 (adds atimeoutand terminatesipairson the stub), #12712 (stub change only), #13276 and #12916 (bounds the scan more broadly). Which one lands is the maintainer's decision.Checked by Claude Opus 5.5 against the source on
quattro, with no code run. Codex at medium effort was asked separately whether the two issues are the same and agreed; its independence is not guaranteed.