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.
Cloned menu gets null appLibrary — manifestHasKind Array.isArray fails on QVariantList kinds
Reported by CJ-Montero · filed Oct 7, 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 (menu) — 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
Title: Cloned menu gets null appLibrary — manifestHasKind Array.isArray fails on QVariantList kinds
What happened
After cloning omarchy.menu to cjmontero.menu (only change: Spanish
"Desinstalar" strings), the Apps submenu is completely empty. The menu opens,
the apps provider entry exists, but mergeAppRows() aborts because the
scoped shell ships appLibrary = null for the clone. Stock (first-party)
menu works because it receives the global shell directly.
Shell log evidence (from temporary logging in the clone, since removed):
CJDEBUG mergeAppRows hasShell=true shellAppLib=false pluginId=cjmontero.menu manifestKinds=["menu","bar-widget"] items=334
CJDEBUG mergeAppRows ABORT no appLibraryA standalone Quickshell probe on the same machine lists 52 desktop entries
(~35 visible after launcher.hides filtering), so the data is there — the
clone just never receives it.
What was expected
A cloned menu (clonedFrom: omarchy.menu, kinds ["menu","bar-widget"],
enabled, stock disabled) receives a working appLibrary like the stock menu,
so Apps lists installed applications.
Steps to reproduce
omarchy plugin clone omarchy.menu(or equivalent clone to<user>.menu)- Confirm bar uses the clone and stock
omarchy.menuis disabled omarchy-shell shell summon omarchy.menu '{"menu":"apps"}'(or open Apps from the menu)- Apps submenu is empty; shell log shows
appLibrarynull inmergeAppRows()
Root cause
shell.qml manifestHasKind() uses Array.isArray(manifest.kinds).
A manifest that reaches the panel path through the Instantiator as modelData
carries kinds as a QVariantList, and Array.isArray() is false for those
even though they index like an array — so the check fails, the scoped shell
is built with appLibrary: null, and the result is cached.
Proposed patch (shell.qml)
Duck-type instead of Array.isArray, so it holds for both plain JS arrays
and QVariantList:
function manifestHasKind(manifest, kind) {
// A manifest that reached us through a model — the panel Instantiator hands
// out modelData — carries kinds as a QVariantList, and Array.isArray() is
// false for those even though they index like an array.
var kinds = manifest ? manifest.kinds : null
return !!kinds && typeof kinds.indexOf === "function"
&& kinds.indexOf(kind) !== -1
}Reported as verified by the reporter: with the patch the same shell logs
rows in mergeAppRows() and the Apps submenu renders normally.
Note: the other three Array.isArray(m.kinds) sites (isBarOptionManifest,computePanelEntries, _syncServices) only ever see raw registry manifests,
never modelData, so they are not affected — though aligning them would be
consistent.
System details
- Omarchy: 4.0.4-1 (
omarchy version) - Base: Arch Linux rolling, Hyprland (Wayland),
XDG_CURRENT_DESKTOP=Hyprland - CPU: Intel(R) Core(TM) i5-6500TE CPU @ 2.30GHz
- GPU: Intel Corporation Skylake-S GT2 [HD Graphics 530] (rev 06)
- Note:
omarchy debugdoes not exist in 4.0.4-1
(Unknown Omarchy command), so no debug-log URL; diagnostics above are
from the shell journal (journalctl --user -t omarchy-shell) and a
Quickshell DesktopEntries probe.
Local workaround (kept out of this report's scope)
Menu-side fallback inside the clone (cjmontero.menu/Menu.qml only):
list DesktopEntries directly with the same hide rules whenroot.appLibrary is null. Works, but the one-line upstream fix above is
the correct resolution.
View raw text
Title: Cloned menu gets null appLibrary — manifestHasKind Array.isArray fails on QVariantList kinds
## What happened
After cloning `omarchy.menu` to `cjmontero.menu` (only change: Spanish
"Desinstalar" strings), the Apps submenu is completely empty. The menu opens,
the `apps` provider entry exists, but `mergeAppRows()` aborts because the
scoped shell ships `appLibrary = null` for the clone. Stock (first-party)
menu works because it receives the global shell directly.
Shell log evidence (from temporary logging in the clone, since removed):
```
CJDEBUG mergeAppRows hasShell=true shellAppLib=false pluginId=cjmontero.menu manifestKinds=["menu","bar-widget"] items=334
CJDEBUG mergeAppRows ABORT no appLibrary
```
A standalone Quickshell probe on the same machine lists 52 desktop entries
(~35 visible after `launcher.hides` filtering), so the data is there — the
clone just never receives it.
## What was expected
A cloned menu (`clonedFrom: omarchy.menu`, kinds `["menu","bar-widget"]`,
enabled, stock disabled) receives a working `appLibrary` like the stock menu,
so Apps lists installed applications.
## Steps to reproduce
1. `omarchy plugin clone omarchy.menu` (or equivalent clone to `<user>.menu`)
2. Confirm bar uses the clone and stock `omarchy.menu` is disabled
3. `omarchy-shell shell summon omarchy.menu '{"menu":"apps"}'` (or open Apps from the menu)
4. Apps submenu is empty; shell log shows `appLibrary` null in `mergeAppRows()`
## Root cause
`shell.qml` `manifestHasKind()` uses `Array.isArray(manifest.kinds)`.
A manifest that reaches the panel path through the Instantiator as `modelData`
carries `kinds` as a `QVariantList`, and `Array.isArray()` is false for those
even though they index like an array — so the check fails, the scoped shell
is built with `appLibrary: null`, and the result is cached.
## Proposed patch (`shell.qml`)
Duck-type instead of `Array.isArray`, so it holds for both plain JS arrays
and `QVariantList`:
```qml
function manifestHasKind(manifest, kind) {
// A manifest that reached us through a model — the panel Instantiator hands
// out modelData — carries kinds as a QVariantList, and Array.isArray() is
// false for those even though they index like an array.
var kinds = manifest ? manifest.kinds : null
return !!kinds && typeof kinds.indexOf === "function"
&& kinds.indexOf(kind) !== -1
}
```
Reported as verified by the reporter: with the patch the same shell logs
rows in `mergeAppRows()` and the Apps submenu renders normally.
Note: the other three `Array.isArray(m.kinds)` sites (`isBarOptionManifest`,
`computePanelEntries`, `_syncServices`) only ever see raw registry manifests,
never `modelData`, so they are not affected — though aligning them would be
consistent.
## System details
- Omarchy: 4.0.4-1 (`omarchy version`)
- Base: Arch Linux rolling, Hyprland (Wayland), `XDG_CURRENT_DESKTOP=Hyprland`
- CPU: Intel(R) Core(TM) i5-6500TE CPU @ 2.30GHz
- GPU: Intel Corporation Skylake-S GT2 [HD Graphics 530] (rev 06)
- Note: `omarchy debug` does not exist in 4.0.4-1
(`Unknown Omarchy command`), so no debug-log URL; diagnostics above are
from the shell journal (`journalctl --user -t omarchy-shell`) and a
Quickshell `DesktopEntries` probe.
## Local workaround (kept out of this report's scope)
Menu-side fallback inside the clone (`cjmontero.menu/Menu.qml` only):
list `DesktopEntries` directly with the same hide rules when
`root.appLibrary` is null. Works, but the one-line upstream fix above is
the correct resolution.
Also reported as
This defect is tracked under R-5209 (filed Oct 7, 2026). 4 other reports describe the same defect.
Earliest report of this defect: R-860 (filed Sep 7, 2026).
- Oct 7, 2026R-5209 · this report— tracked here
- ·Decided by agents · verified
Open upstream.
- Sep 16, 2026Third-party (cloned) menu plugin: Apps submenu stays empty — shell never grants appLibrary R-494·Decided by agents · verified
Open upstream.
- Sep 17, 2026Third-party menu-kind plugin gets shell.appLibrary === null, leaving Apps submenu empty R-394·Decided by agents · verified
Closed upstream on 2026-10-12 by the bot omarchybot, as a duplicate (target not recorded).
- ·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
- Fixed bypr/14767· confirmed
- Fixed bypr/15053· 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 (menu)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.