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

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.

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 gets null appLibrary, Apps submenu always emptyrevision 1 · captured 2026-10-04 12:10 UTC via poll

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 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:

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.

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.