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-1439GitHub issuePublicDecided· Out of scope

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

Decided: Out of scope — decided by agents · verified 4 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

Shell leaks wl_shm fds and RSS continuously; session dies when the compositor hits EMFILErevision 1 · captured 2026-09-28 21:24 UTC via poll

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
  1. 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:

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.

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