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 plugin gets null appLibrary, Apps submenu always empty
Reported by syvanpera · filed Sep 9, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #10661 (R-860). GitHub close reason: completed.
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
What happened
A cloned menu plugin (omarchy plugin clone omarchy.menu) renders an empty Apps
submenu — "Nothing here yet" — while every other menu route works normally. The
built-in omarchy.menu shows the app list correctly on the same system.
Third-party plugins receive a capability-scoped PluginShellApi instead of the
host shell object, and its appLibrary arrives null even though the
manifest declares kinds: ["menu"], which shell.qml:603 uses to gate the
grant:
appLibrary: shell.manifestHasKind(manifest, "menu")
? shell.pluginAppLibraryFor(cacheKey, key) : null,Logged from an unmodified clone at the moment shell is injected (bar, built
the same way via pluginBarStateFor, is non-null):
shell= PluginShellApi_QMLTYPE_54 appLibrary= null bar= PluginBarStateApi_QMLTYPE_20
startProvider id= apps entry= {"id":"apps",...,"provider":"apps"} loaded= undefined
mergeAppRows: no appLibraryNo warning is logged. pluginAppLibraryFor() returns null only whencreateObject fails, so either that creation is failing silently ormanifestHasKind is false at that point — the manifest passed in does containkinds, since the same object drives computePanelEntries() selecting themenu entry point.
Secondary issue that makes it permanent: Menu.qml startProviderForMenu()
sets providersLoaded[id] = true before calling mergeAppRows(), so the
early if (!root.appLibrary) return caches the empty result and the submenu
never repopulates:
if (entry.provider === "apps") {
root.providersLoaded[id] = true
root.mergeAppRows()
return
}Expected
A cloned menu plugin gets the same app library as the built-in one, and its Apps
submenu lists desktop entries.
Steps to reproduce
omarchy plugin clone omarchy.menu(no edits needed)omarchy restart shellomarchy menu summon apps
The Apps card renders empty. Disabling the clone so built-in omarchy.menu
handles the route restores the full app list, confirming it is the third-party
path rather than the menu code.
Reproduced with kinds: ["menu", "bar-widget"] (as cloned) and withkinds: ["menu"] alone, so it is not related to the dual kind declaration.
System details
- Omarchy 4.0.3-1 (regressed after upgrading 4.0.2-1 -> 4.0.3-1)
- Clone is byte-identical to the shipped
plugins/menu/forMenuModel.js,
BarWidget.qml and Menu.qml (apart from two lines adding Ctrl+N/Ctrl+P
navigation, which are unrelated to item population)
Note on hot-reload
Unrelated but noticed while diagnosing: edits under~/.config/omarchy/plugins/<id>/ log Local plugin changed, reloading: <id>
but the previously compiled QML keeps running. Changes only take effect afteromarchy restart shell, which makes plugin development confusing.
View raw text
### What happened
A cloned menu plugin (`omarchy plugin clone omarchy.menu`) renders an empty Apps
submenu — "Nothing here yet" — while every other menu route works normally. The
built-in `omarchy.menu` shows the app list correctly on the same system.
Third-party plugins receive a capability-scoped `PluginShellApi` instead of the
host `shell` object, and its `appLibrary` arrives **null** even though the
manifest declares `kinds: ["menu"]`, which `shell.qml:603` uses to gate the
grant:
```qml
appLibrary: shell.manifestHasKind(manifest, "menu")
? shell.pluginAppLibraryFor(cacheKey, key) : null,
```
Logged from an unmodified clone at the moment `shell` is injected (`bar`, built
the same way via `pluginBarStateFor`, is non-null):
```
shell= PluginShellApi_QMLTYPE_54 appLibrary= null bar= PluginBarStateApi_QMLTYPE_20
startProvider id= apps entry= {"id":"apps",...,"provider":"apps"} loaded= undefined
mergeAppRows: no appLibrary
```
No warning is logged. `pluginAppLibraryFor()` returns null only when
`createObject` fails, so either that creation is failing silently or
`manifestHasKind` is false at that point — the manifest passed in does contain
`kinds`, since the same object drives `computePanelEntries()` selecting the
`menu` entry point.
Secondary issue that makes it permanent: `Menu.qml` `startProviderForMenu()`
sets `providersLoaded[id] = true` *before* calling `mergeAppRows()`, so the
early `if (!root.appLibrary) return` caches the empty result and the submenu
never repopulates:
```qml
if (entry.provider === "apps") {
root.providersLoaded[id] = true
root.mergeAppRows()
return
}
```
### Expected
A cloned menu plugin gets the same app library as the built-in one, and its Apps
submenu lists desktop entries.
### Steps to reproduce
1. `omarchy plugin clone omarchy.menu` (no edits needed)
2. `omarchy restart shell`
3. `omarchy menu summon apps`
The Apps card renders empty. Disabling the clone so built-in `omarchy.menu`
handles the route restores the full app list, confirming it is the third-party
path rather than the menu code.
Reproduced with `kinds: ["menu", "bar-widget"]` (as cloned) and with
`kinds: ["menu"]` alone, so it is not related to the dual kind declaration.
### System details
- Omarchy 4.0.3-1 (regressed after upgrading 4.0.2-1 -> 4.0.3-1)
- Clone is byte-identical to the shipped `plugins/menu/` for `MenuModel.js`,
`BarWidget.qml` and `Menu.qml` (apart from two lines adding Ctrl+N/Ctrl+P
navigation, which are unrelated to item population)
### Note on hot-reload
Unrelated but noticed while diagnosing: edits under
`~/.config/omarchy/plugins/<id>/` log `Local plugin changed, reloading: <id>`
but the previously compiled QML keeps running. Changes only take effect after
`omarchy restart shell`, which makes plugin development confusing.
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.