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-5074GitHub issuePublicReceived

Cloned menu plugin receives null shell, so its Apps submenu is always empty

Reported by Current-Version · filed Sep 14, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #10661 (R-860). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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?
Not yet mapped to any requirement or component.
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. No decision has been recorded yet.

Original report

Cloned menu plugin receives null shell, so its Apps submenu is always emptyrevision 1 · captured 2026-10-04 12:10 UTC via poll

What happened

After omarchy plugin clone omarchy.menu and making layout-only changes to the
clone (moved the card bottom-left, added a header/footer — no logic changes),
the Apps submenu in the cloned menu is permanently empty ("Nothing here
yet"). Search, static rows, and bash-backed providers (fonts, power-profiles)
all work in the clone.

Diagnosis

I added a temporary probe method to the clone's Menu.qml and queried the
live shell over IPC on a fresh process:

omarchy-shell shell call rsanchez.menu debugApps '{}'
→ shell=NULL manifest=["menu","bar-widget"]

So the panel Loader instantiates the clone (manifest is injected, UI renders),
but shell.pluginShellFor(panelEntry.manifest) returns null, leaving
root.shell = null and therefore root.appLibrary unreachable. mergeAppRows
early-returns, and Apps can never populate. The quickshell log shows zero QML
errors when opening Apps — it fails silently.

Expected

A clone whose manifest keeps kind "menu" should receive the scoped shell
including appLibrary, per createScopedPluginShell +
manifestHasKind(manifest, "menu").

Suspected location

shell.qml: pluginShellFor(manifest) → createScopedPluginShell(...).
The manifest carries id + kinds (verified via listPlugins and by reading
root.manifest from the live instance), so the likely failure is
pluginShellApiComponent.createObject(...) returning null for a third-party
manifest. I did not modify anything under /usr/share/omarchy.

Steps to reproduce

  1. omarchy plugin clone omarchy.menu (bar switches to <user>.menu)
  2. Open the menu → Apps
  3. Empty, forever. Equivalently, expose root.shell from the clone and observe

it is null, while root.manifest.kinds is ["menu","bar-widget"].

System details

  • Omarchy 4.0.3-1, Quickshell 0.3.1 (Arch), Hyprland 0.56.2
  • CPU AMD Ryzen AI Max+ 395, GPU AMD Strix Halo (Radeon 8060S)
  • Full probe transcript + plugin state: attached file omarchy-clone-menu-bug.txt

Workaround I'm using

A bash-backed programs provider in the clone that scans .desktop files
directly (honoring NoDisplay/Hidden and the default launcher.hides) with
the apps entry repointed at it via omarchy-menu.jsonc. Works, minus
per-app icons.

No screenshot attached: capturing the empty state would require reverting a
working menu; the IPC probe output above is the precise evidence.


Diagnostics bundle

Omarchy cloned-menu null-shell diagnostics
==========================================
Date: 2026-09-14
Omarchy version: 4.0.3-1
Quickshell: 0.3.1 (Arch Linux)
Hyprland: 0.56.2
CPU: AMD RYZEN AI MAX+ 395 w/ Radeon 8060S
GPU: AMD Strix Halo Radeon 8060S
Theme at time of diagnosis: windows-xp (custom, ~/.config/omarchy/themes/windows-xp)

Plugin state (omarchy-shell shell listPlugins):
  rsanchez.menu | enabled | ['menu', 'bar-widget']   (clone of omarchy.menu)
  omarchy.menu  | disabled | ['menu', 'bar-widget']  (stock, auto-disabled by clone)

Clone manifest id/kinds verified present:
  id: rsanchez.menu, kinds: ["menu", "bar-widget"], omarchy.clonedFrom: omarchy.menu

Live IPC probe (temporary debugApps() method added to the CLONE's Menu.qml,
queried on a fresh shell process via
`omarchy-shell shell call rsanchez.menu debugApps '{}'`):

  BEFORE fix attempt: appLibrary=NULL rowsLoaded=true activeMenu=root displayCount=0
  AFTER refining probe: shell=NULL manifest=["menu","bar-widget"]

Interpretation: the panel Loader instantiated the clone fine (manifest
injected, static JSONC rows render, search works, bash providers work,
no QML errors in the quickshell log when opening Apps), but
`shell.pluginShellFor(panelEntry.manifest)` (shell.qml, panel Loader
onLoaded) returned null, so `root.shell` is null and `root.appLibrary`
(derived from it) is unreachable. The Apps submenu therefore never
merges rows and shows "Nothing here yet".

Relevant host code (all under /usr/share/omarchy/shell/shell.qml, read-only):
  - panel Loader onLoaded: item.shell = shell.pluginShellFor(panelEntry.manifest)
  - pluginShellFor(manifest): returns null only if manifest id is empty or
    createScopedPluginShell(...) returns null
  - createScopedPluginShell: returns null only if manifest id is empty or
    pluginShellApiComponent.createObject(...) returns null
Since the manifest has id + kinds, suspicion falls on the createObject call
(or an expression inside its property map) failing for third-party manifests.

Other evidence:
  - Stock-vs-clone diff of Menu.qml at diagnosis time: layout/anchors only
    (card position, header/footer, cardWidth); all provider/model logic
    byte-identical to stock.
  - 90 .desktop files on disk (/usr/share/applications + ~/.local/share/...).
  - Fresh quickshell log: zero QML errors on `omarchy menu summon apps`.
  - `omarchy-shell shell call rsanchez.menu ping '{}'` -> ok (clone reachable).

User-scope workaround applied (all under ~/.config):
  - Added a "programs" bash provider to the clone enumerating .desktop files
    (skips NoDisplay/Hidden, applies default launcher.hides, launches via
    `uwsm-app -- gtk-launch <id>.desktop`, same as AppLibrary.launch).
  - Overrode the "apps" entry in
    ~/.config/omarchy/extensions/omarchy-menu.jsonc with provider "programs".
  Result: Apps lists 39 programs (no per-app icons — provider rows carry one
  shared glyph).
View raw text
## What happened
After `omarchy plugin clone omarchy.menu` and making layout-only changes to the
clone (moved the card bottom-left, added a header/footer — no logic changes),
the **Apps** submenu in the cloned menu is permanently empty ("Nothing here
yet"). Search, static rows, and bash-backed providers (fonts, power-profiles)
all work in the clone.

## Diagnosis
I added a temporary probe method to the clone's `Menu.qml` and queried the
live shell over IPC on a fresh process:

```
omarchy-shell shell call rsanchez.menu debugApps '{}'
→ shell=NULL manifest=["menu","bar-widget"]
```

So the panel `Loader` instantiates the clone (manifest is injected, UI renders),
but `shell.pluginShellFor(panelEntry.manifest)` returns **null**, leaving
`root.shell = null` and therefore `root.appLibrary` unreachable. `mergeAppRows`
early-returns, and Apps can never populate. The quickshell log shows zero QML
errors when opening Apps — it fails silently.

## Expected
A clone whose manifest keeps kind `"menu"` should receive the scoped shell
including `appLibrary`, per `createScopedPluginShell` +
`manifestHasKind(manifest, "menu")`.

## Suspected location
`shell.qml`: `pluginShellFor(manifest)` → `createScopedPluginShell(...)`.
The manifest carries id + kinds (verified via `listPlugins` and by reading
`root.manifest` from the live instance), so the likely failure is
`pluginShellApiComponent.createObject(...)` returning null for a third-party
manifest. I did not modify anything under `/usr/share/omarchy`.

## Steps to reproduce
1. `omarchy plugin clone omarchy.menu` (bar switches to `<user>.menu`)
2. Open the menu → **Apps**
3. Empty, forever. Equivalently, expose `root.shell` from the clone and observe
   it is null, while `root.manifest.kinds` is `["menu","bar-widget"]`.

## System details
- Omarchy 4.0.3-1, Quickshell 0.3.1 (Arch), Hyprland 0.56.2
- CPU AMD Ryzen AI Max+ 395, GPU AMD Strix Halo (Radeon 8060S)
- Full probe transcript + plugin state: attached file `omarchy-clone-menu-bug.txt`

## Workaround I'm using
A bash-backed `programs` provider in the clone that scans `.desktop` files
directly (honoring `NoDisplay`/`Hidden` and the default `launcher.hides`) with
the `apps` entry repointed at it via `omarchy-menu.jsonc`. Works, minus
per-app icons.

No screenshot attached: capturing the empty state would require reverting a
working menu; the IPC probe output above is the precise evidence.

---

## Diagnostics bundle
```
Omarchy cloned-menu null-shell diagnostics
==========================================
Date: 2026-09-14
Omarchy version: 4.0.3-1
Quickshell: 0.3.1 (Arch Linux)
Hyprland: 0.56.2
CPU: AMD RYZEN AI MAX+ 395 w/ Radeon 8060S
GPU: AMD Strix Halo Radeon 8060S
Theme at time of diagnosis: windows-xp (custom, ~/.config/omarchy/themes/windows-xp)

Plugin state (omarchy-shell shell listPlugins):
  rsanchez.menu | enabled | ['menu', 'bar-widget']   (clone of omarchy.menu)
  omarchy.menu  | disabled | ['menu', 'bar-widget']  (stock, auto-disabled by clone)

Clone manifest id/kinds verified present:
  id: rsanchez.menu, kinds: ["menu", "bar-widget"], omarchy.clonedFrom: omarchy.menu

Live IPC probe (temporary debugApps() method added to the CLONE's Menu.qml,
queried on a fresh shell process via
`omarchy-shell shell call rsanchez.menu debugApps '{}'`):

  BEFORE fix attempt: appLibrary=NULL rowsLoaded=true activeMenu=root displayCount=0
  AFTER refining probe: shell=NULL manifest=["menu","bar-widget"]

Interpretation: the panel Loader instantiated the clone fine (manifest
injected, static JSONC rows render, search works, bash providers work,
no QML errors in the quickshell log when opening Apps), but
`shell.pluginShellFor(panelEntry.manifest)` (shell.qml, panel Loader
onLoaded) returned null, so `root.shell` is null and `root.appLibrary`
(derived from it) is unreachable. The Apps submenu therefore never
merges rows and shows "Nothing here yet".

Relevant host code (all under /usr/share/omarchy/shell/shell.qml, read-only):
  - panel Loader onLoaded: item.shell = shell.pluginShellFor(panelEntry.manifest)
  - pluginShellFor(manifest): returns null only if manifest id is empty or
    createScopedPluginShell(...) returns null
  - createScopedPluginShell: returns null only if manifest id is empty or
    pluginShellApiComponent.createObject(...) returns null
Since the manifest has id + kinds, suspicion falls on the createObject call
(or an expression inside its property map) failing for third-party manifests.

Other evidence:
  - Stock-vs-clone diff of Menu.qml at diagnosis time: layout/anchors only
    (card position, header/footer, cardWidth); all provider/model logic
    byte-identical to stock.
  - 90 .desktop files on disk (/usr/share/applications + ~/.local/share/...).
  - Fresh quickshell log: zero QML errors on `omarchy menu summon apps`.
  - `omarchy-shell shell call rsanchez.menu ping '{}'` -> ok (clone reachable).

User-scope workaround applied (all under ~/.config):
  - Added a "programs" bash provider to the clone enumerating .desktop files
    (skips NoDisplay/Hidden, applies default launcher.hides, launches via
    `uwsm-app -- gtk-launch <id>.desktop`, same as AppLibrary.launch).
  - Overrode the "apps" entry in
    ~/.config/omarchy/extensions/omarchy-menu.jsonc with provider "programs".
  Result: Apps lists 39 programs (no per-app icons — provider rows carry one
  shared glyph).
```

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.

No decision has been recorded yet.