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.
Plugin hot-reload duplicates IPC handlers and leaks GPU surfaces until VRAM exhausts and the bar dies
Reported by ghpo · filed Sep 8, 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
Environment
- Omarchy: 4.0.2-1 (omarchy-shell / quickshell 0.3.1-1)
- Hyprland: 0.56.2
- Kernel: 7.1.9-arch1-2
- GPU: 2x NVIDIA GeForce RTX 3080 (GA102), nvidia-open-dkms / nvidia-utils 610.57.04-1 (GPU 0 drives the displays, DRM backend)
- CPU: Intel Xeon E5-2678 v3
- User plugin involved: a cloned user plugin under
~/.config/omarchy/plugins/(git repo, being actively edited/committed)
Summary
Hot-reloading a user plugin (any file change under ~/.config/omarchy/plugins/) does not reliably tear down the previous scene. Each reload logs duplicated IpcHandler registrations for essentially every bar widget/panel, and after enough reloads the shell leaks GPU surfaces until the NVIDIA driver can no longer allocate VRAM. At that point every panel/popup window fails to initialize its OpenGL context, so clicking any bar icon (weather, network, audio, etc.) does nothing — the popup simply never renders.
What I observed
- Each plugin file save triggers repeated reloads:
DEBUG qml: Local plugin changed, reloading: ghpo.quicknote
DEBUG qml: Local plugin changed, reloading: ghpo.quicknote (x8 at once)- Right after every reload the same widgets/panels register their IPC target a second time and are rejected:
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/bar/widgets/Indicators.qml[168:3]:
Handler was registered but will not be used because another handler is registered for target omarchy.indicators
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/panels/weather/Panel.qml[476:3]:
Handler was registered but will not be used because another handler is registered for target omarchy.weather
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/panels/network/Panel.qml[210:3]: ... omarchy.network
... (agents, system-update, audio, bluetooth, clock, monitor, power, tailscale)- After an evening of plugin editing (~1h), GPU VRAM saturates and the kernel starts failing every allocation:
[drm:nv_drm_gem_alloc_nvkms_memory_ioctl [nvidia_drm]] *ERROR* [nvidia-drm] [GPU ID 0x00000300]
Failed to allocate NVKMS memory for GEM object nvidia-smi showed 9733 MiB / 10240 MiB used, of which only ~600 MiB is attributable to live processes (Hyprland 141 MiB, quickshell 147 MiB, Xwayland 4 MiB, sunshine 298 MiB, nextcloud 20 MiB). ~9 GB is orphaned/leaked with no owning process.
- The shell then fails to create graphics contexts for its layer windows, which is why popups/panels stop appearing on click:
WARN: Failed to create RHI (backend 2)
ERROR: Failed to create graphics context for qs::wayland::layershell::WlrLayershell(...):
"Failed to initialize graphics backend for OpenGL."
WARN qt.qpa.wayland: Could not create EGL surface (EGL error 0x3003)
WARN qt.qpa.wayland: eglSwapBuffers failed with 0x300d, surface: 0x0omarchy restart shelldoes not recover the VRAM — the orphaned allocation belongs to the NVIDIA driver (NVKMS) and is only reclaimed by a module reload/reboot. The leak also starts again on a fresh shell once reloads resume.
Steps to reproduce
- Clone a user plugin (e.g.
omarchy plugin clone omarchy.clockor any own plugin) and add it to the bar in~/.config/omarchy/shell.json. - Repeatedly save/edit files under
~/.config/omarchy/plugins/<id>/(or trigger severalLocal plugin changedreloads in a row). - While doing so, watch:
journalctl --user -f | grep "another handler is registered"— duplicates appear on each reload.nvidia-smi— used VRAM climbs after each reload burst and never comes back down.
- After enough reloads, kernel log shows
Failed to allocate NVKMS memory for GEM objectand clicking bar icons no longer opens panels.
Expected behavior
- A plugin reload should fully destroy the previous widget/panel instances (and their GPU surfaces) before instantiating the new ones — no duplicate
IpcHandlerregistrations, no monotonically growing VRAM. - Even if a reload does churn, repeated reloads must not be able to exhaust GPU memory and permanently wedge the bar until reboot.
Notes
- Files under
~/.config/omarchy/plugins/kept being rewritten (identical content, clean git tree) at the same instants as the reload bursts, feeding the reload loop — it looks like the watcher can re-trigger itself. - The shell code comments around
loadPluginWidget(shell.qml, "A load already in flight ... briefly running two of the widget, each registering its IPC handler") acknowledge a duplicate-instance risk during asynchronous loads; the reload path appears to hit the same class of problem for panels/widgets.
View raw text
## Environment
- Omarchy: 4.0.2-1 (omarchy-shell / quickshell 0.3.1-1)
- Hyprland: 0.56.2
- Kernel: 7.1.9-arch1-2
- GPU: 2x NVIDIA GeForce RTX 3080 (GA102), nvidia-open-dkms / nvidia-utils 610.57.04-1 (GPU 0 drives the displays, DRM backend)
- CPU: Intel Xeon E5-2678 v3
- User plugin involved: a cloned user plugin under `~/.config/omarchy/plugins/` (git repo, being actively edited/committed)
## Summary
Hot-reloading a user plugin (any file change under `~/.config/omarchy/plugins/`) does not reliably tear down the previous scene. Each reload logs duplicated `IpcHandler` registrations for essentially every bar widget/panel, and after enough reloads the shell leaks GPU surfaces until the NVIDIA driver can no longer allocate VRAM. At that point every panel/popup window fails to initialize its OpenGL context, so **clicking any bar icon (weather, network, audio, etc.) does nothing** — the popup simply never renders.
## What I observed
1. Each plugin file save triggers repeated reloads:
```
DEBUG qml: Local plugin changed, reloading: ghpo.quicknote
DEBUG qml: Local plugin changed, reloading: ghpo.quicknote (x8 at once)
```
2. Right after every reload the same widgets/panels register their IPC target a second time and are rejected:
```
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/bar/widgets/Indicators.qml[168:3]:
Handler was registered but will not be used because another handler is registered for target omarchy.indicators
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/panels/weather/Panel.qml[476:3]:
Handler was registered but will not be used because another handler is registered for target omarchy.weather
WARN scene: QML IpcHandler at file:///usr/share/omarchy/shell/plugins/panels/network/Panel.qml[210:3]: ... omarchy.network
... (agents, system-update, audio, bluetooth, clock, monitor, power, tailscale)
```
3. After an evening of plugin editing (~1h), GPU VRAM saturates and the kernel starts failing every allocation:
```
[drm:nv_drm_gem_alloc_nvkms_memory_ioctl [nvidia_drm]] *ERROR* [nvidia-drm] [GPU ID 0x00000300]
Failed to allocate NVKMS memory for GEM object
```
`nvidia-smi` showed **9733 MiB / 10240 MiB used**, of which only ~600 MiB is attributable to live processes (Hyprland 141 MiB, quickshell 147 MiB, Xwayland 4 MiB, sunshine 298 MiB, nextcloud 20 MiB). ~9 GB is orphaned/leaked with no owning process.
4. The shell then fails to create graphics contexts for its layer windows, which is why popups/panels stop appearing on click:
```
WARN: Failed to create RHI (backend 2)
ERROR: Failed to create graphics context for qs::wayland::layershell::WlrLayershell(...):
"Failed to initialize graphics backend for OpenGL."
WARN qt.qpa.wayland: Could not create EGL surface (EGL error 0x3003)
WARN qt.qpa.wayland: eglSwapBuffers failed with 0x300d, surface: 0x0
```
5. `omarchy restart shell` does **not** recover the VRAM — the orphaned allocation belongs to the NVIDIA driver (NVKMS) and is only reclaimed by a module reload/reboot. The leak also starts again on a fresh shell once reloads resume.
## Steps to reproduce
1. Clone a user plugin (e.g. `omarchy plugin clone omarchy.clock` or any own plugin) and add it to the bar in `~/.config/omarchy/shell.json`.
2. Repeatedly save/edit files under `~/.config/omarchy/plugins/<id>/` (or trigger several `Local plugin changed` reloads in a row).
3. While doing so, watch:
- `journalctl --user -f | grep "another handler is registered"` — duplicates appear on each reload.
- `nvidia-smi` — used VRAM climbs after each reload burst and never comes back down.
4. After enough reloads, kernel log shows `Failed to allocate NVKMS memory for GEM object` and clicking bar icons no longer opens panels.
## Expected behavior
- A plugin reload should fully destroy the previous widget/panel instances (and their GPU surfaces) before instantiating the new ones — no duplicate `IpcHandler` registrations, no monotonically growing VRAM.
- Even if a reload does churn, repeated reloads must not be able to exhaust GPU memory and permanently wedge the bar until reboot.
## Notes
- Files under `~/.config/omarchy/plugins/` kept being rewritten (identical content, clean git tree) at the same instants as the reload bursts, feeding the reload loop — it looks like the watcher can re-trigger itself.
- The shell code comments around `loadPluginWidget` (shell.qml, "A load already in flight ... briefly running two of the widget, each registering its IPC handler") acknowledge a duplicate-instance risk during asynchronous loads; the reload path appears to hit the same class of problem for panels/widgets.
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 11:06 UTC