Skip to content

omarchy-menu-keybindings hangs forever when user Lua config iterates an hl.get_*() result #14243

Open

Description

@KouenNoTen

Omarchy version: 4.0.4 (Lua Hyprland config)

What happens

SUPER+K never opens the keybindings menu. omarchy-menu-keybindings --print hangs with no output. Each press leaves a lua process spinning at 100% CPU (I had 18), and an empty ~/.cache/omarchy/keybindings.XXXXXX file behind (I had ~70).

Cause

build_lua_bind_cache loads ~/.config/hypr/hyprland.lua against a stub hl. Unknown fields resolve to noop, whose __index and __call both return noop:

local noop
noop = setmetatable({}, {
  __index = function() return noop end,
  __call  = function() return noop end,
})

So hl.get_monitors() (or any hl.get_*()) returns noop, and noop[i] is never nil. Any user config that runs at load time like

for _, monitor in ipairs(hl.get_monitors()) do ... end

loops forever (ipairs honours __index, Lua 5.5). The bash while read loop around the lua <<'LUA' heredoc then waits forever too.

Minimal repro

Add to ~/.config/hypr/hyprland.lua:

for _ in ipairs(hl.get_monitors()) do end

Hyprland itself is fine, but omarchy-menu-keybindings --print now never returns.

Suggested fixes

  1. Make the stub safe to iterate. For example, have noop's __index return nil for integer keys, or have stubbed hl.get_* return {}.
  2. Run the Lua scan under a timeout, so a bad user config degrades the menu (e.g. no Lua binds listed) rather than hanging it.
  3. In refresh_keybindings_cache, clean up tmp_file with a trap on EXIT/INT/TERM. Today it is only removed when output_binding_records_uncached returns non-zero, so a hung or killed run leaks it.

Workaround

In user config, copy hl.get_*() results with rawget(t, i) before iterating.

Activity

  1. jandrusk commented on Oct 6, 2026

    @jandrusk

    Thanks for the minimal repro. This is the same bug as #7025, which is the issue being kept open for the noop stub + ipairs hang. Earlier reports (#9052, #8819, #10214, #11094) were closed into it. Open fixes are #7564 (make the Lua bind scan safe against load-time config reads) and #11733 (read bindings from the running compositor instead). Your trap point about leaked keybindings.XXXXXX temp files would be a good addition there if neither PR covers it yet.

  2. omarchybot commented on Oct 18, 2026

    @omarchybot
    Collaborator

    Thanks for the clear repro and the diagnosis. I checked current quattro, and the noop stub in build_lua_bind_cache is unchanged, so the hang is still live. Claude Opus 5.5 classified this as a bug, and Codex Medium agreed separately.

    This is the bug #7025 tracks, and an open pull request already fixes it. #7564 makes the stub answer nil for numeric keys and runs the scan under timeout 10. Its tests include this exact loop, for _, monitor in ipairs(hl.get_monitors()) do. On a worker, those tests fail on quattro and pass on the pull request's head. #11733 takes a different approach: it reads bindings from the running compositor instead of replaying the config. That one has not been verified yet. Which of the two lands is the maintainer's call.

    I did not close this as a duplicate of #7025, because Codex Medium did not agree they are the same report. I also tried to add this issue to #7564's closing references, but that was refused: #7564 has new commits since it was classified, so it has to be classified again first. Your third point, removing the leaked keybindings.XXXXXX temp file with a trap, is not covered by #7564's change to bin/omarchy-menu-keybindings. The timeout ends the hang, but a killed run can still leave the file behind.

    This now waits on the maintainer: picking between #7564 and #11733, and deciding whether this issue closes with #7025.

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 working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions