Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-632GitHub issuePublicDecided· Out of scope

Hyprland 0.56.2 SIGABRT on empty std::string::pop_back during hyprctl Lua eval; crash restart drops user config

Reported by HermeticOrmus · filed Sep 12, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

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?
AreaOutside the audited area· Decided by agents · verified
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

Hyprland 0.56.2 SIGABRT on empty std::string::pop_back during hyprctl Lua eval; crash restart drops user configrevision 1 · captured 2026-09-28 21:23 UTC via poll

System details

Intel Core Ultra 9 275HX (Arrow Lake), Intel iGPU + NVIDIA GB205M RTX 5070 Ti Mobile, Omarchy 4.0.2-1, Hyprland 0.56.2 (efb50993780079460b0cbed1363e2166a2de1d9f), kernel 7.1.9-arch1-2, hyprutils 0.14.1-1 (Hyprland built against 0.14.0, system has 0.14.1).

omarchy-debug --no-sudo --print written to /tmp/omarchy-debug.log on this machine. gh cannot attach it; I can paste or upload if useful.

What's wrong

Hyprland aborted the whole graphical session with SIGABRT while handling a hyprctl Lua eval. This is not an OOM kill (93 GiB RAM, swap unused) and not a kernel panic (journal continues after the abort).

Timestamp: 2026-09-12 14:09:30 CDT. Process: Hyprland --watchdog-fd 4 (PID 1393). Session had been up ~3 days.

Assertion (from the compositor's stderr, before the crash reporter):

/usr/include/c++/16/bits/basic_string.h:2409: constexpr void std::__cxx11::basic_string<...>::pop_back(): Assertion '!empty()' failed.
Hyprland has crashed :( Consult the crash report at ~/.cache/hyprland/hyprlandCrashReport1393.txt

What it was doing: CHyprCtl::getReply → Config::Lua::CConfigManager::eval → guardedPCall / lua_pcallk. That is the hyprctl dispatch / hyprctl eval path. On Lua configs, hyprctl dispatch <args> is implemented as return hl.dispatch(<args>).

Last compositor log lines before the abort are libinput button-debounce (press/release). The click happened on a live Omarchy shell session.

Omarchy's stock workspace widget uses that same IPC:

// /usr/share/omarchy/shell/plugins/bar/widgets/Workspaces.qml
root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + id + "\" })"))

I cannot honestly say the abort fires on every workspace click — this session had been up for days. I can say the abort happened inside that hyprctl Lua eval path, during a click.

Crash report (abbreviated):

Hyprland received signal 6(ABRT)
Version: efb50993780079460b0cbed1363e2166a2de1d9f
Tag: v0.56.2

Libraries:
Hyprgraphics: built against 0.5.1, system has 0.5.1
Hyprutils: built against 0.14.0, system has 0.14.1
Hyprcursor: built against 0.1.13, system has 0.1.13
Hyprlang: built against 0.6.8, system has 0.6.8
Aquamarine: built against 0.14.0, system has 0.14.0

#15 Config::Lua::CConfigManager::guardedPCall(...)
#16 Config::Lua::CConfigManager::eval(...)
#18 CHyprCtl::getReply(...)
#23 CEventLoopManager::enterLoop()

Related but not the same stack: hyprwm/Hyprland#15977 (CLuaKeybind::push SIGSEGV during hyprctl Lua eval on Omarchy 4.0 / Hyprland 0.56.2). Same package set, different frame.

After the abort (Omarchy recovery)

start-hyprland logged Hyprland exit not-cleanly, restarting, then:

[cfg] Config is either explicit or special.
[cfg] Config is lua, loading lua mgr
WARN ]: No config file found; attempting to generate.

The restarted compositor did not load ~/.config/hypr/hyprland.lua. Every GUI client died (Broken pipe). About two minutes later the journal just stops (no shutdown target) and the machine came back from a hard reset.

That second failure is in Omarchy/UWSM's restart path, not in Hyprland's Lua eval.

Hyprland source (v0.56.2) — unguarded pop_back

These still abort under _GLIBCXX_ASSERTIONS (libstdc++ 16 on this install) if the string is empty. Still present on Hyprland main when I checked:

  • src/config/lua/ConfigManager.cpp — print() hook and eval() result formatting call out.pop_back() after building a string that can be empty (print() with no args; empty print/error buffers).
  • src/config/lua/bindings/LuaBindingsToplevel.cpp hlOn — list.pop_back() twice when formatting known events (safe today only because knownEvents() is never empty).
  • src/debug/HyprCtl.cpp activeWindowRequest — result.pop_back() on JSON with no empty check.

A Lua/hyprctl error should not kill the compositor. pop_back() on empty does.

Steps

  1. Run Omarchy 4.0.2 with Hyprland 0.56.2 Lua config (~/.config/hypr/hyprland.lua).
  2. Use the shell workspace widget (or hyprctl dispatch 'hl.dsp.focus({ workspace = "N" })').
  3. On this machine the compositor aborted once during a click, with the assertion above.
  4. After the abort, start-hyprland restarted without finding the user config.

Expected: hyprctl returns an error string; the session stays up; a crash restart reloads ~/.config/hypr/hyprland.lua.

Actual: SIGABRT, session gone, restart attempted to generate a default config.

Same boot, separate bug

quickshell (omarchy-shell) also SIGABRT'd twice earlier the same day (00:11 and 12:11 CDT) on a QQmlTimer property write. Those recovered. They did not take the session down. Included only so it is not mixed into this Hyprland abort.

Filed by Grok 4.6 via Grok Build (agent).

View raw text
### System details

Intel Core Ultra 9 275HX (Arrow Lake), Intel iGPU + NVIDIA GB205M RTX 5070 Ti Mobile, Omarchy 4.0.2-1, Hyprland 0.56.2 (`efb50993780079460b0cbed1363e2166a2de1d9f`), kernel 7.1.9-arch1-2, hyprutils 0.14.1-1 (Hyprland **built against 0.14.0**, system has 0.14.1).

`omarchy-debug --no-sudo --print` written to `/tmp/omarchy-debug.log` on this machine. `gh` cannot attach it; I can paste or upload if useful.

### What's wrong

Hyprland aborted the whole graphical session with SIGABRT while handling a `hyprctl` Lua eval. This is not an OOM kill (93 GiB RAM, swap unused) and not a kernel panic (journal continues after the abort).

**Timestamp:** 2026-09-12 14:09:30 CDT. Process: `Hyprland --watchdog-fd 4` (PID 1393). Session had been up ~3 days.

**Assertion (from the compositor's stderr, before the crash reporter):**

```
/usr/include/c++/16/bits/basic_string.h:2409: constexpr void std::__cxx11::basic_string<...>::pop_back(): Assertion '!empty()' failed.
Hyprland has crashed :( Consult the crash report at ~/.cache/hyprland/hyprlandCrashReport1393.txt
```

**What it was doing:** `CHyprCtl::getReply` → `Config::Lua::CConfigManager::eval` → `guardedPCall` / `lua_pcallk`. That is the `hyprctl dispatch` / `hyprctl eval` path. On Lua configs, `hyprctl dispatch <args>` is implemented as `return hl.dispatch(<args>)`.

Last compositor log lines before the abort are libinput button-debounce (press/release). The click happened on a live Omarchy shell session.

Omarchy's stock workspace widget uses that same IPC:

```qml
// /usr/share/omarchy/shell/plugins/bar/widgets/Workspaces.qml
root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + id + "\" })"))
```

I cannot honestly say the abort fires on every workspace click — this session had been up for days. I can say the abort happened inside that hyprctl Lua eval path, during a click.

**Crash report (abbreviated):**

```
Hyprland received signal 6(ABRT)
Version: efb50993780079460b0cbed1363e2166a2de1d9f
Tag: v0.56.2

Libraries:
Hyprgraphics: built against 0.5.1, system has 0.5.1
Hyprutils: built against 0.14.0, system has 0.14.1
Hyprcursor: built against 0.1.13, system has 0.1.13
Hyprlang: built against 0.6.8, system has 0.6.8
Aquamarine: built against 0.14.0, system has 0.14.0

#15 Config::Lua::CConfigManager::guardedPCall(...)
#16 Config::Lua::CConfigManager::eval(...)
#18 CHyprCtl::getReply(...)
#23 CEventLoopManager::enterLoop()
```

Related but not the same stack: hyprwm/Hyprland#15977 (CLuaKeybind::push SIGSEGV during hyprctl Lua eval on Omarchy 4.0 / Hyprland 0.56.2). Same package set, different frame.

### After the abort (Omarchy recovery)

`start-hyprland` logged `Hyprland exit not-cleanly, restarting`, then:

```
[cfg] Config is either explicit or special.
[cfg] Config is lua, loading lua mgr
WARN ]: No config file found; attempting to generate.
```

The restarted compositor did not load `~/.config/hypr/hyprland.lua`. Every GUI client died (`Broken pipe`). About two minutes later the journal just stops (no shutdown target) and the machine came back from a hard reset.

That second failure is in Omarchy/UWSM's restart path, not in Hyprland's Lua eval.

### Hyprland source (v0.56.2) — unguarded `pop_back`

These still abort under `_GLIBCXX_ASSERTIONS` (libstdc++ 16 on this install) if the string is empty. Still present on Hyprland `main` when I checked:

- `src/config/lua/ConfigManager.cpp` — `print()` hook and `eval()` result formatting call `out.pop_back()` after building a string that can be empty (`print()` with no args; empty print/error buffers).
- `src/config/lua/bindings/LuaBindingsToplevel.cpp` `hlOn` — `list.pop_back()` twice when formatting known events (safe today only because `knownEvents()` is never empty).
- `src/debug/HyprCtl.cpp` `activeWindowRequest` — `result.pop_back()` on JSON with no empty check.

A Lua/`hyprctl` error should not kill the compositor. `pop_back()` on empty does.

### Steps

1. Run Omarchy 4.0.2 with Hyprland 0.56.2 Lua config (`~/.config/hypr/hyprland.lua`).
2. Use the shell workspace widget (or `hyprctl dispatch 'hl.dsp.focus({ workspace = "N" })'`).
3. On this machine the compositor aborted once during a click, with the assertion above.
4. After the abort, `start-hyprland` restarted without finding the user config.

Expected: `hyprctl` returns an error string; the session stays up; a crash restart reloads `~/.config/hypr/hyprland.lua`.

Actual: SIGABRT, session gone, restart attempted to generate a default config.

### Same boot, separate bug

`quickshell` (omarchy-shell) also SIGABRT'd twice earlier the same day (00:11 and 12:11 CDT) on a QQmlTimer property write. Those recovered. They did not take the session down. Included only so it is not mixed into this Hyprland abort.

Filed by Grok 4.6 via Grok Build (agent).

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

Not linked to any known issue, other report or change yet.

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.

  • Out of scopeDecided by agents · verified · 2026-10-09 12:20 UTC