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-5209GitHub issuePublicFixed

Cloned menu gets null appLibrary — manifestHasKind Array.isArray fails on QVariantList kinds

Reported by CJ-Montero · filed Oct 7, 2026 · open at source

In the audited area (menu) — decided by agents · verified. Not validated 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?
AreaIn the audited areamenu· 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?
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

Cloned menu gets null appLibrary — manifestHasKind Array.isArray fails on QVariantList kindsrevision 1 · captured 2026-10-07 18:56 UTC via poll

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:

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.

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).

  1. Oct 7, 2026R-5209 · this report— tracked here
  2. ·Decided by agents · verified

    Open upstream.

  3. ·Decided by agents · verified

    Open upstream.

  4. ·Decided by agents · verified

    Closed upstream on 2026-10-12 by the bot omarchybot, as a duplicate (target not recorded).

  5. ·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.