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.
Shell leaks wl_shm fds and RSS continuously; session dies when the compositor hits EMFILE
Reported by cashea · filed Aug 26, 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?
- 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
What happens
The Omarchy shell (quickshell -n -p /usr/share/omarchy/shell) accumulates wl_shm
buffer file descriptors and RSS for as long as it runs, with an idle desktop and no
user interaction. It is also the dominant driver of a matching fd leak in Hyprland,
which ends the session in a compositor abort.
My Hyprland session died twice this way on 2026-08-24 (20:51 and 22:35 PDT).
Expected
A shell sitting idle should hold a steady number of buffers.
Evidence — shell side
Single quickshell process, no restarts, 54 minutes old:
quickshell pid=56066 uptime=3251s fds=5122 RSS=623 MB4,900 of those 5,122 fds are read-only handles to deleted /dev/shm/<uuid> segments.
Two segments dominate and keep growing:
inode 23 : 2005 fds held by quickshell
inode 7 : 498 fds held by quickshellThe shell's own journal is clean — 53 lines this boot, config loaded twice, no errors
that account for this. It leaks silently while behaving normally.
Worth noting: nothing in the environment forces software rendering
(QT_QPA_PLATFORM=wayland;xcb), so I do not have an explanation for why the shell is
on the wl_shm path rather than dmabuf on this machine. That may be the actual root —
if the shell used the GPU path there would be no shm churn to leak.
I could not separate quickshell-upstream behaviour from Omarchy's QML without
instrumenting the shell, so I am not asserting which side owns it.
Evidence — compositor side, and why the session dies
Hyprland accumulates ~8x more fds for the same segments and never releases them,
including after the client exits:
uptime : 4425s
total fds : 44162 / 524288
wl_shm fds : 43024
client exited: 17549 (across 213 dead segments)
inode 23: Hyprland = 16571 fds vs quickshell = 2005 fdsIdle growth, nothing animating: +1091 wl_shm fds in 30 seconds.
That Hyprland half is a separate upstream bug. It was already reported as
hyprwm/Hyprland#14662 (2026-05-18) and auto-closed nine seconds later by the
no-user-issues bot, never triaged; I am raising it again in their Discussions with the
compositor-side evidence. Note #14662 identifies the trigger precisely as
transparent zwlr_layer_shell_v1 surfaces using wl_shm -- which is what the Omarchy
bar is. It is here because the shell is what drives it hardest, and because the
combination is what kills an Omarchy session.
The failure chain
- Shell allocates wl_shm buffers continuously; neither side releases them
- Hyprland walks its fd table to EMFILE — confirmed in both crash reports:
GPU: <pipe(pipefd) failed with24> (errno 24 = EMFILE)
3. It can no longer dup dmabuf/sync fds:
eglCreateImageKHR ... could not bind to DMA buffer
4. Clients stall; the ANR watchdog fires and spawns hyprland-dialog
5. Those dialogs cannot be handed a DRM fd either — they get -1 and abort:
m_drmState = {fd = -1, nodeName = ""}
#3 Hyprtoolkit::COpenGLRenderer::COpenGLRenderer hyprtoolkit-0.5.4/src/renderer/gl/OpenGL.cpp:421
RASSERT(false, "Couldn't open a gbm fd");
#5 Hyprtoolkit::IBackend::create hyprtoolkit-0.5.4/src/core/Backend.cpp:109
#6 main hyprland-guiutils-0.2.2/utils/dialog/src/main.cpp:108- The next input-capture session cannot allocate its EIS backend fd; libeis asserts
and takes the compositor with it:
assertion "eis->backend" failed, ../libei/src/libeis-fd.c:78, eis_backend_fd_add_client
<- CInputCaptureResource::CInputCaptureResource src/protocols/InputCapture.cpp:46uwsm relaunches Hyprland immediately, so from the user's side the whole desktop
flashes and comes back with everything closed.
Reproduce
Log in and leave the desktop idle. Watch both counters climb:
HP=$(pgrep -x Hyprland | head -1); QS=$(pgrep -x quickshell | head -1)
watch -n30 "echo Hyprland=\$(ls /proc/$HP/fd|wc -l) quickshell=\$(ls /proc/$QS/fd|wc -l)"Mitigation available to users today
omarchy-restart-shellreclaims the shell's fds but not the compositor's —
those are only released when Hyprland restarts
- The only full reset is logging out and back in
- No configuration change avoids it
System
Omarchy 4.0.1-1
Hyprland 0.56.2-1 quickshell 0.3.1-1
hyprtoolkit 0.5.4-4 hyprland-guiutils 0.2.2-2
aquamarine 0.14.0-2 libei 1.6.0-1
Kernel 7.1.8-arch1-3
GPU NVIDIA GeForce RTX 3080 (GA102), nvidia-open-dkms 610.57.04-1
mesa 1:26.2.1-1 (1:26.1.8-1 at the time of both crashes)
Monitors 2x 2048x1152 @ scale 2 (DP-1, DP-2)
Machine ASUS ROG STRIX B550-I, Ryzen 7 5800X, 31 GiB RAMUpstream references:
- hyprwm/Hyprland#14662 -- same defect, client-side symptom, auto-closed untriaged
- hyprwm/hyprtoolkit -- the hyprland-dialog abort, filed separately
Full diagnostics available from omarchy debug --no-sudo --print on request.
Filed by Claude Opus 5 via Claude Code.
View raw text
## What happens
The Omarchy shell (`quickshell -n -p /usr/share/omarchy/shell`) accumulates wl_shm
buffer file descriptors and RSS for as long as it runs, with an idle desktop and no
user interaction. It is also the dominant driver of a matching fd leak in Hyprland,
which ends the session in a compositor abort.
My Hyprland session died twice this way on 2026-08-24 (20:51 and 22:35 PDT).
## Expected
A shell sitting idle should hold a steady number of buffers.
## Evidence — shell side
Single quickshell process, no restarts, 54 minutes old:
```
quickshell pid=56066 uptime=3251s fds=5122 RSS=623 MB
```
4,900 of those 5,122 fds are read-only handles to deleted `/dev/shm/<uuid>` segments.
Two segments dominate and keep growing:
```
inode 23 : 2005 fds held by quickshell
inode 7 : 498 fds held by quickshell
```
The shell's own journal is clean — 53 lines this boot, config loaded twice, no errors
that account for this. It leaks silently while behaving normally.
Worth noting: nothing in the environment forces software rendering
(`QT_QPA_PLATFORM=wayland;xcb`), so I do not have an explanation for why the shell is
on the wl_shm path rather than dmabuf on this machine. That may be the actual root —
if the shell used the GPU path there would be no shm churn to leak.
I could not separate quickshell-upstream behaviour from Omarchy's QML without
instrumenting the shell, so I am not asserting which side owns it.
## Evidence — compositor side, and why the session dies
Hyprland accumulates ~8x more fds for the same segments and never releases them,
including after the client exits:
```
uptime : 4425s
total fds : 44162 / 524288
wl_shm fds : 43024
client exited: 17549 (across 213 dead segments)
inode 23: Hyprland = 16571 fds vs quickshell = 2005 fds
```
Idle growth, nothing animating: **+1091 wl_shm fds in 30 seconds.**
That Hyprland half is a separate upstream bug. It was already reported as
hyprwm/Hyprland#14662 (2026-05-18) and auto-closed nine seconds later by the
no-user-issues bot, never triaged; I am raising it again in their Discussions with the
compositor-side evidence. Note #14662 identifies the trigger precisely as
**transparent zwlr_layer_shell_v1 surfaces using wl_shm** -- which is what the Omarchy
bar is. It is here because the shell is what drives it hardest, and because the
combination is what kills an Omarchy session.
## The failure chain
1. Shell allocates wl_shm buffers continuously; neither side releases them
2. Hyprland walks its fd table to EMFILE — confirmed in both crash reports:
`GPU: <pipe(pipefd) failed with24>` (errno 24 = EMFILE)
3. It can no longer dup dmabuf/sync fds:
`eglCreateImageKHR ... could not bind to DMA buffer`
4. Clients stall; the ANR watchdog fires and spawns `hyprland-dialog`
5. Those dialogs cannot be handed a DRM fd either — they get `-1` and abort:
```
m_drmState = {fd = -1, nodeName = ""}
#3 Hyprtoolkit::COpenGLRenderer::COpenGLRenderer hyprtoolkit-0.5.4/src/renderer/gl/OpenGL.cpp:421
RASSERT(false, "Couldn't open a gbm fd");
#5 Hyprtoolkit::IBackend::create hyprtoolkit-0.5.4/src/core/Backend.cpp:109
#6 main hyprland-guiutils-0.2.2/utils/dialog/src/main.cpp:108
```
6. The next input-capture session cannot allocate its EIS backend fd; libeis asserts
and takes the compositor with it:
```
assertion "eis->backend" failed, ../libei/src/libeis-fd.c:78, eis_backend_fd_add_client
<- CInputCaptureResource::CInputCaptureResource src/protocols/InputCapture.cpp:46
```
uwsm relaunches Hyprland immediately, so from the user's side the whole desktop
flashes and comes back with everything closed.
## Reproduce
Log in and leave the desktop idle. Watch both counters climb:
```bash
HP=$(pgrep -x Hyprland | head -1); QS=$(pgrep -x quickshell | head -1)
watch -n30 "echo Hyprland=\$(ls /proc/$HP/fd|wc -l) quickshell=\$(ls /proc/$QS/fd|wc -l)"
```
## Mitigation available to users today
- `omarchy-restart-shell` reclaims the shell's fds but **not** the compositor's —
those are only released when Hyprland restarts
- The only full reset is logging out and back in
- No configuration change avoids it
## System
```
Omarchy 4.0.1-1
Hyprland 0.56.2-1 quickshell 0.3.1-1
hyprtoolkit 0.5.4-4 hyprland-guiutils 0.2.2-2
aquamarine 0.14.0-2 libei 1.6.0-1
Kernel 7.1.8-arch1-3
GPU NVIDIA GeForce RTX 3080 (GA102), nvidia-open-dkms 610.57.04-1
mesa 1:26.2.1-1 (1:26.1.8-1 at the time of both crashes)
Monitors 2x 2048x1152 @ scale 2 (DP-1, DP-2)
Machine ASUS ROG STRIX B550-I, Ryzen 7 5800X, 31 GiB RAM
```
Upstream references:
- hyprwm/Hyprland#14662 -- same defect, client-side symptom, auto-closed untriaged
- hyprwm/hyprtoolkit -- the `hyprland-dialog` abort, filed separately
Full diagnostics available from `omarchy debug --no-sudo --print` on request.
---
Filed by Claude Opus 5 via Claude Code.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 09:13 UTC