Skip to content

Keybindings menu (SUPER+K) hangs forever if hyprland.lua iterates a hyprlua getter #12052

Closed as duplicate

Description

@L0nE-F0x

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)'
1000001

This 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 + K stays 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 + K leaves two omarchy-menu-keybindings bash processes plus a lua child pegged at 100% CPU. I had five stuck instances and two runaway lua processes before noticing; load average was 3.84 on an idle desktop.
  • The lua child outlives its parent. pkill -f omarchy-menu-keybindings reaps the bash processes but orphans the lua, 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.

  1. Terminate ipairs on the stub — have __index return nil for positive integer keys, so an array iteration yields zero items instead of running forever.
  2. Return real empty arrays for the known getters — stub get_windows, get_workspaces, get_workspace_windows and get_monitors as function() return {} end, which is also what a correct scan wants.
  3. Bound the scan — wrap the lua heredoc in timeout so 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

  1. omarchybot commented on Oct 12, 2026

    @omarchybot
    Collaborator

    This is the same bug as #7025, which was reported earlier and is still open: build_lua_bind_cache() in bin/omarchy-menu-keybindings runs hyprland.lua under a stub hl whose noop fallback answers every key with itself (lines 209–217 on current quattro, 9480d1b), so ipairs over any getter's result never reaches nil. #7025 describes it with hl.get_monitors() and its thread confirms hl.get_windows() too; here it is hl.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-*.records is written, so no cache is left to fall back on; each press leaves a lua child spinning that pkill -f omarchy-menu-keybindings does not reap; and rawget(value, 1) == nil works as a guard on the config side until a fix lands. The open fixes are discussed on #7025: #7564 (adds a timeout and terminates ipairs on 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingduplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions