Unofficial community reference. Not affiliated with 37signals or the Omacom Foundation. Download Omarchy only from omarchy.org.
omarchylinux.org Unofficial field manual

attempt to index a nil value (global 'o')

Hyprland starts with no bindings, no monitors and a config-error banner after Quattro. Your hyprland.lua never loads Omarchy's helpers, so the global o is nil.

Workaround available Applies to Omarchy 3.x Last verified 2026-09-16 on 4.0.4
Short answer

Your ~/.config/hypr/hyprland.lua is an old copy that never loads Omarchy's helpers, so the global o is nil and every default module fails. Switch to a TTY with Ctrl+Alt+F2 and run omarchy refresh hyprland, which backs up your file and restores the stock entrypoint. Then re-add your personal lines to hypr/bindings.lua and hypr/monitors.lua instead.

On this page
  1. The fix
  2. Verify it worked
  3. Why it happens
  4. What changed between 3.x and 4.x
  5. If that did not work
  6. Related

Hyprland comes up with the red config-error banner, no keybindings, no monitor layout and no autostarted apps. hyprctl configerrors lists the same message once per Omarchy module:

require("default.hypr.autostart"): .../default/hypr/autostart.lua:1: attempt to index a nil value (global 'o')
require("default.hypr.bindings.media"): .../media.lua:2: attempt to index a nil value (global 'o')

The file at fault is always ~/.config/hypr/hyprland.lua, not the module the error names.

The fix

You probably cannot open the Omarchy menu or a terminal, because the bindings that launch them never loaded. Get a text console first.

  1. Press Ctrl + Alt + F2 and log in at the TTY prompt.

  2. Look at the top of your entrypoint:

    head -15 ~/.config/hypr/hyprland.lua

    A healthy 4.x file has a dofile(...) line ending in /default/hypr/bootstrap.lua near the top and, about ten lines down, require("default.hypr.omarchy"). If either is missing, that is your bug.

  3. Restore the shipped entrypoint:

    omarchy refresh hyprland

    This runs omarchy-refresh-hyprland, which copies each of hyprland.lua, bindings.lua, monitors.lua, input.lua, looknfeel.lua, autostart.lua and .luarc.json from /usr/share/omarchy/config/hypr into ~/.config/hypr. Every file it replaces is saved first as <file>.bak.<unix-timestamp> in the same directory, and the command prints a diff of what changed.

  4. Log out and back in, or reboot.

  5. Copy your personal lines out of the .bak. files into ~/.config/hypr/bindings.lua and ~/.config/hypr/monitors.lua. Do not put them back into hyprland.lua. The stock entrypoint loads those override files after the defaults for exactly this reason.

If you want to keep your hyprland.lua as it is

Two lines are enough. Edit ~/.config/hypr/hyprland.lua from the TTY and make sure the top of the file reads:

dofile((os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/default/hypr/bootstrap.lua")

require("default.hypr.omarchy")

Everything that uses o must come after those, including your own require("hypr.bindings") and any o.window(...) you added at the bottom. Then log out and back in.

If your file still carries the older 4.0 alpha preamble (a hand-built package.path = ... block and require("default.hypr.paths")), the minimal repair people used in May 2026 was to add require("default.hypr.helpers") before the first require("default.hypr.*") line. That works, but on 4.0.4 you are better off moving to the bootstrap dofile, because the bootstrap also adds ~/.local/state/?.lua to the search path, and on 4.0.4 the current theme’s Hyprland module is loaded from ~/.local/state/omarchy/current/theme/.

Verify it worked

From a graphical session:

hyprctl reload
hyprctl configerrors

Omarchy’s own agent notes use that pair as the validation step after any Lua config change. A clean result prints no errors. Then check that the things that were missing are back: Super + K opens the keybindings list, Super + Space opens the menu, and your wallpaper and bar are up.

Why it happens

In Quattro the global o is not a Hyprland builtin. It is created by /usr/share/omarchy/default/hypr/helpers.lua, which starts with o = o or {} and then hangs o.bind, o.window, o.launch_on_start and the rest off that table. Nothing else defines it. helpers.lua is the first module default/hypr/omarchy.lua requires, and default.hypr.omarchy is the one line through which the shipped hyprland.lua loads every default.

So o is nil whenever your entrypoint reaches a default module without going through default.hypr.omarchy first. Three real ways that happens:

  • You carried an old hyprland.lua forward. A file written during the 4.0 alpha requires default.hypr.autostart and friends directly, with no helpers line. This is what issue #5879 documents, and what issues #5814, #5822 and #5824 were all hitting in May 2026 on the dev channel and 4.0 alpha builds.
  • Your package.path still points at the 3.x location. Before 4.0, OMARCHY_PATH was $HOME/.local/share/omarchy. On 4.x it is /usr/share/omarchy, because Omarchy is a pacman package now. A restored dotfiles copy of the old preamble searches a directory that no longer holds the defaults, so every require("default.hypr.*") fails and o never gets defined.
  • You reordered the requires. Putting require("hypr.bindings") above require("default.hypr.omarchy") runs your o.bind calls before o exists.

Omarchy ships migration 1781063758.sh (“Update Hyprland Lua entrypoint to load Omarchy bootstrap”, dated 2026-06-10) to rewrite the old preamble into the bootstrap dofile automatically. It is present in every 4.0.x tag from 4.0.0 through 4.0.4. It skips any file that already contains /default/hypr/bootstrap.lua, which is why fresh 4.0 installs are never affected.

The migration is also why this page says workaround rather than fixed. Issue #7103, filed by an automated QA pass in August 2026 and still open, shows that once the migration’s awk has matched the old preamble, it discards input until it meets a line that is exactly .. package.path. If you had rewrapped that assignment or appended your own path entry, no line matches, the discard runs to the end of the file, and a two-line config is written back with no backup. PR #11222 rewrites it to consume the assignment by its continuation lines and to save a copy as hyprland.lua.omarchy-bootstrap.bak first. That PR was still open on 2026-09-16.

What changed between 3.x and 4.x

On 3.8.4, the last 3.x release, ~/.config/hypr held hyprland.conf, bindings.conf, monitors.conf and the rest. There was no Lua and no o. The May 2026 reports in this cluster came from people on the dev channel or 4.0 alpha builds running a pre-release Lua config against Hyprland 0.55, and dhh’s answer at the time was to go back to the stable channel via Update > Channel > Stable. That advice is dead on 4.x. Quattro moved the whole config to Lua, and there is no .conf path to fall back to.

If that did not work

  • Still broken after the refresh. Two people in issue #5879 reported that only removing the whole directory worked. Move it aside rather than deleting it: mv ~/.config/hypr ~/hypr.broken && omarchy refresh hyprland, then reboot and pull your edits back from ~/hypr.broken.
  • Your hyprland.lua is now two lines long. That is issue #7103. Omarchy’s Snapper config covers the root subvolume only (SUBVOLUME="/" in default/snapper/root), and PR #11222 notes that /home is not in the pre-update snapshot. In practice omarchy refresh hyprland plus rewriting your bindings is the recovery.
  • A different Lua error. A Runtime error in lua popup after unbinding a key is issue #9005, and a bad_any_cast crash on mouse input under Hyprland 0.56.2 is issue #10912. Both were open on 2026-09-16 and neither is a missing o.
  • The error appeared during an update rather than after one. See /fix/migration-failed-mid-update/.

The manual chapter that covers these files is Dotfiles. It lists what each ~/.config/hypr/*.lua file is for and shows the hl.unbind plus o.bind pattern for replacing a default binding.

Upstream threads about this error

7 issues on the Omarchy tracker match this error cluster. Newest fixes often appear as comments on the most-discussed threads.

IssueStateCommentsOpened
#5797 Omarchy 3.8.0 breaks hyprlandclosed142026-05-13
#5814 hyprland user config brokenclosed122026-05-14
#5824 New update breaks hyperlandclosed72026-05-15
#5822 dev commit e916491c9f1805be292ed274e59d99921c71398b breaks all hyprland lua filesclosed82026-05-14
#5879 Existing ~/.config/hypr/hyprland.lua not migrated to load default.hypr.helpers after 4.0 update — attempt to index a nil value (global 'o') · fixed by #79 open42026-05-16
#5911 Missing migration: helpers.lua not loaded in existing hyprland.lua after update · fixed by #79 closed12026-05-19
#12642 Shipped a2dp_source auto-connect makes a paired phone silence all audioopen02026-09-20

Questions people ask

Will omarchy refresh hyprland delete my customizations?
It overwrites the seven shipped files in ~/.config/hypr with the Omarchy defaults, but omarchy-refresh-config copies each one to <file>.bak.<timestamp> first. Your old content is still on disk, so you can copy your bindings back out of the backup.
Can I just downgrade Hyprland instead?
No. On 4.x the Lua config is the only config. The channel switch that dhh recommended in May 2026 applied to Omarchy 3.8 running against Hyprland 0.55, before Quattro shipped. Going back to stable on 4.0.4 does not give you a .conf setup.
Why does the error name autostart.lua when I never edited it?
Every Omarchy default module calls o.something on its first lines. The module that fails first is just the first one your entrypoint requires. The broken file is your hyprland.lua, not the module named in the error.

Sources and credit

Fixes on this page were worked out by Cyrus-n8n (Traced the error to helpers.lua never being required from the user entrypoint), alipadron (Posted the one-line require fix with the surrounding config context), felixzsh (Pointed people at omarchy refresh hyprland as the recovery command), vovarbv (Reproduced the truncation of a hand-edited hyprland.lua and opened the PR that stops it). Text here is our own paraphrase; follow the links for the original threads.

Unofficial. Verify against the official manual for your version. Improve this page Markdown version Sources