Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA 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.
omarchy-shell lock screen crash-loops (~every 18s) after locking, due to DPMS-off
Reported by ultgames · filed Aug 19, 2026 · open at source
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?
- 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?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: in the audited area (lock) — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Original report
System details
AMD Radeon RX 570/580/590 Omarchy 4.0
What's wrong?
Summary
After the Quattro upgrade, the omarchy-shell lock screen crashes with a Wayland/EGL
fatal error almost every time it needs to create its lock surface — both on resume
from suspend, and on a normal idle-timeout lock. It usually self-recovers within a
few seconds via the shell's own "lock-stranded: recovering" logic, but recovery is
not guaranteed to land in time, and when it doesn't, Hyprland falls through to its
native crashed-lockscreen fallback screen ("Oopsie daisy, it looks like you locked
your screen but the lockscreen app died"), requiring TTY-based recovery
(hyprctl --instance 0 eval 'hl.clear_crashed_lockscreen()' or killall -9 hyprlock).
This looks related to older pre-Quattro hyprlock crash-on-resume reports (#5935,
#5521), but those were against direct hyprlock invocation. Quattro replaced that
with a shell-owned lock (omarchy-shell lock lock via WlSessionLock), and the
same class of "EGL context not ready" race reappears through the new code path.
I couldn't find an existing issue against the Quattro/omarchy-shell architecture
specifically, so filing this as (possibly) new.
Crash signature (from journalctl)
omarchy-shell[PID]: WARN qt.qpa.wayland: Could not create EGL surface (EGL error 0x3000)
omarchy-shell[PID]: WARN qt.qpa.wayland: eglSwapBuffers failed with 0x300d, surface: 0x0
omarchy-shell[PID]: WARN: The Wayland connection experienced a fatal error: Invalid argument
omarchy-shell[PID2]: Omarchy shell exited with status 255; relaunching.
omarchy-shell[PID3]: DEBUG qml: omarchy lock <timestamp> lock-stranded: recoveringReproduction / frequency
On the boot that started right after the Quattro upgrade (2026-08-15 14:59) through
2026-08-19, out of 5 suspend/resume cycles, 4 produced this exact crash sequence on
resume. All 4 self-recovered within a few seconds, but at least one occurrence did
not recover in time and produced the native Hyprland "lockscreen app died" fallback
screen, requiring a TTY switch to recover.
Separately, the same crash also fires on a normal **idle-timeout lock with no
suspend involved**, if the screensaver is disabled
(omarchy-toggle-screensaver). Root cause for that path, traced inshell/plugins/services/idle/Service.qml:
shell.json'sidle.screensaver(default 150s) andidle.lock(default 300s)
both start counting from the same idle-start event.
- screensaverDelaySeconds is computed as `screensaverTimeoutSeconds -
min(screensaverTimeoutSeconds, lockTimeoutSeconds)`, so the screensaver launch
always fires at the 150s mark regardless of whether it's enabled.
- With the screensaver enabled, that puts a terminal window on screen which keeps
the compositor actively rendering until the 300s lock timer fires.
- With the screensaver disabled, omarchy-launch-screensaver exits instantly
(early-exits on the screensaver-off toggle check), so the compositor sits fully
idle with nothing rendering for the entire 150s→300s window — leaving it just as
"cold" as a post-suspend compositor by the time the lock timer fires and
omarchy-system-lock → omarchy-shell lock lock tries to create the
WlSessionLockSurface.
- Confirmed via journal timestamps on 2026-08-19: idle-cycle-start at 11:21:12 →
screensaver process exitCode=1 at 11:21:13 (toggled off, no window ever opens)
→ crash (Wayland connection experienced a fatal error) at 11:23:59 — ~167s
later, matching the 150s lock-delay window closely enough to not be coincidence.
Re-enabling the screensaver eliminates this second (idle-timeout) trigger, since it
keeps the compositor warm during the wait. It does not affect the
resume-from-suspend trigger, which still reproduces regardless of screensaver state.
Likely proximate cause
In shell/plugins/lock/Service.qml, sessionLockStabilizeTimer is a **hardcoded
500ms** Timer that fires after a Quickshell.screens change (e.g. resume, or a
lock request) and then calls requestSessionLock(), which setssessionLock.locked = true — this is what causes Quickshell to create theWlSessionLockSurface, and that EGL surface creation is what's failing. 500ms may
not be enough time for amdgpu/Mesa to have the output pipeline fully ready after
outputs have just come back from being off/idle, and there's no shell.json
config knob exposed for this delay — increasing it, and/or retrying EGL surface
creation instead of letting the whole shell process crash, seem like the likely
fix directions.
Workaround tried
Re-enabling the screensaver (omarchy-toggle-screensaver) fixes the idle-lock
trigger but not the resume-from-suspend trigger.
Recovery when it happens
# from another TTY (ctrl+alt+F[N])
hyprctl --instance 0 eval 'hl.clear_crashed_lockscreen()'
# if that doesn't help:
killall -9 hyprlockView raw text
### System details
AMD Radeon RX 570/580/590 Omarchy 4.0
### What's wrong?
## Summary
After the Quattro upgrade, the `omarchy-shell` lock screen crashes with a Wayland/EGL
fatal error almost every time it needs to create its lock surface — both on resume
from suspend, and on a normal idle-timeout lock. It usually self-recovers within a
few seconds via the shell's own "lock-stranded: recovering" logic, but recovery is
not guaranteed to land in time, and when it doesn't, Hyprland falls through to its
native crashed-lockscreen fallback screen ("Oopsie daisy, it looks like you locked
your screen but the lockscreen app died"), requiring TTY-based recovery
(`hyprctl --instance 0 eval 'hl.clear_crashed_lockscreen()'` or `killall -9 hyprlock`).
This looks related to older pre-Quattro hyprlock crash-on-resume reports (#5935,
#5521), but those were against direct hyprlock invocation. Quattro replaced that
with a shell-owned lock (`omarchy-shell lock lock` via `WlSessionLock`), and the
same class of "EGL context not ready" race reappears through the new code path.
I couldn't find an existing issue against the Quattro/omarchy-shell architecture
specifically, so filing this as (possibly) new.
## Crash signature (from `journalctl`)
```
omarchy-shell[PID]: WARN qt.qpa.wayland: Could not create EGL surface (EGL error 0x3000)
omarchy-shell[PID]: WARN qt.qpa.wayland: eglSwapBuffers failed with 0x300d, surface: 0x0
omarchy-shell[PID]: WARN: The Wayland connection experienced a fatal error: Invalid argument
omarchy-shell[PID2]: Omarchy shell exited with status 255; relaunching.
omarchy-shell[PID3]: DEBUG qml: omarchy lock <timestamp> lock-stranded: recovering
```
## Reproduction / frequency
On the boot that started right after the Quattro upgrade (2026-08-15 14:59) through
2026-08-19, out of 5 suspend/resume cycles, 4 produced this exact crash sequence on
resume. All 4 self-recovered within a few seconds, but at least one occurrence did
not recover in time and produced the native Hyprland "lockscreen app died" fallback
screen, requiring a TTY switch to recover.
Separately, the same crash also fires on a normal **idle-timeout lock with no
suspend involved**, if the screensaver is disabled
(`omarchy-toggle-screensaver`). Root cause for that path, traced in
`shell/plugins/services/idle/Service.qml`:
- `shell.json`'s `idle.screensaver` (default 150s) and `idle.lock` (default 300s)
both start counting from the same idle-start event.
- `screensaverDelaySeconds` is computed as `screensaverTimeoutSeconds -
min(screensaverTimeoutSeconds, lockTimeoutSeconds)`, so the screensaver launch
always fires at the 150s mark **regardless of whether it's enabled**.
- With the screensaver enabled, that puts a terminal window on screen which keeps
the compositor actively rendering until the 300s lock timer fires.
- With the screensaver **disabled**, `omarchy-launch-screensaver` exits instantly
(early-exits on the `screensaver-off` toggle check), so the compositor sits fully
idle with nothing rendering for the entire 150s→300s window — leaving it just as
"cold" as a post-suspend compositor by the time the lock timer fires and
`omarchy-system-lock` → `omarchy-shell lock lock` tries to create the
`WlSessionLockSurface`.
- Confirmed via journal timestamps on 2026-08-19: `idle-cycle-start` at 11:21:12 →
screensaver process `exitCode=1` at 11:21:13 (toggled off, no window ever opens)
→ crash (`Wayland connection experienced a fatal error`) at 11:23:59 — ~167s
later, matching the 150s lock-delay window closely enough to not be coincidence.
Re-enabling the screensaver eliminates this second (idle-timeout) trigger, since it
keeps the compositor warm during the wait. It does **not** affect the
resume-from-suspend trigger, which still reproduces regardless of screensaver state.
## Likely proximate cause
In `shell/plugins/lock/Service.qml`, `sessionLockStabilizeTimer` is a **hardcoded
500ms** `Timer` that fires after a `Quickshell.screens` change (e.g. resume, or a
lock request) and then calls `requestSessionLock()`, which sets
`sessionLock.locked = true` — this is what causes Quickshell to create the
`WlSessionLockSurface`, and that EGL surface creation is what's failing. 500ms may
not be enough time for amdgpu/Mesa to have the output pipeline fully ready after
outputs have just come back from being off/idle, and there's no `shell.json`
config knob exposed for this delay — increasing it, and/or retrying EGL surface
creation instead of letting the whole shell process crash, seem like the likely
fix directions.
## Workaround tried
Re-enabling the screensaver (`omarchy-toggle-screensaver`) fixes the idle-lock
trigger but not the resume-from-suspend trigger.
## Recovery when it happens
```bash
# from another TTY (ctrl+alt+F[N])
hyprctl --instance 0 eval 'hl.clear_crashed_lockscreen()'
# if that doesn't help:
killall -9 hyprlock
```
Also reported as
This defect is tracked under R-1659 (filed Aug 19, 2026). 10 other reports describe the same defect.
Earliest report of this defect: R-1882 (filed Aug 8, 2026).
- Aug 19, 2026R-1659 · this report— tracked here
- Aug 8, 2026Lock shell dies during normal idle->lock; session permanently locked, reboot required R-1882·Decided by agents · verified
Open upstream.
- Aug 30, 2026Shell lock client dies on resume from suspend, showing Hyprland 'screensaver died' failsafe R-1219· via R-709·Decided by agents · verified
Open upstream.
- ·Decided by agents · verified
Open upstream.
- ·Decided by agents · verified
Open upstream.
- ·Decided by agents · verified
Open upstream.
- ·Decided by arbitration
Open upstream.
- Sep 16, 2026Lock screen blanking crashes the shell on single-monitor setups, causing a lock/relaunch loop R-491·Decided by agents · verified
Open upstream.
- Sep 17, 2026Idle blank is undone by the idle wake path when the monitor's link flaps, strobing black/lock screen R-392·Decided by agents · verified
Open upstream.
- · via R-709·Decided by agents · verified
Open upstream.
- Oct 6, 2026Lock screen loops shell crash and monitor power-cycle when HDMI output drops after DPMS off R-5178·Decided by agents · verified
Open upstream.
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
- Related PRpr/6642· confirmed
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.
- Decided by agents · verified: in the audited area (lock)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.