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.
bar.shell.serviceFor() returns null for third-party service+bar-widget plugins
Reported by n30nf4nt0m · filed Sep 14, 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?
- AreaOutside the audited area· 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?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
What happened
For a third-party plugin that declares both "service" and "bar-widget" kinds in its manifest, the bar-widget's bar.shell.serviceFor(pluginId) call reliably returns null, even though:
- the service itself loads and runs correctly (its own IPC target responds, and it persists state to disk correctly)
bar.shellexists andbar.shell.serviceForis a genuine function (not missing/undefined)
Since a plugin's BarWidget.qml/Panel.qml typically guard every interactive control with if (!svc) return, this makes every button, tab, toggle, and slider in the plugin's popup a silent no-op — the popup opens and displays correctly (since static labels don't need svc), but nothing in it does anything, and slider drags visually "snap back" after release (because the value binding re-reads from the unchanged service state).
Steps to reproduce
- Install a plugin whose
manifest.jsonhas:
"kinds": ["service", "bar-widget"],
"entryPoints": { "service": "Service.qml", "barWidget": "BarWidget.qml" }- In
BarWidget.qml, add a diagnostic to confirm the failure, e.g. in atooltipText:
tooltipText: "bar=" + (root.bar ? "Y" : "N")
+ " shell=" + (root.bar && root.bar.shell ? "Y" : "N")
+ " serviceForFn=" + (root.bar && root.bar.shell && typeof root.bar.shell.serviceFor === "function" ? "Y" : "N")
+ " svc=" + (root.svc ? "Y" : "N") where svc is bar && bar.shell ? bar.shell.serviceFor(pluginId) : null.
3. Restart the shell (omarchy restart shell) and hover the widget's bar icon.
Observed
bar=Y shell=Y serviceForFn=Y svc=N — the lookup function exists and is callable, but returns null.
Confirmed independently that the service itself is alive and controllable the whole time, e.g.:
quickshell -p /usr/share/omarchy/shell ipc call <service-ipc-target> <method> <args>correctly mutates and persists the plugin's own state file, while the widget's bar.shell.serviceFor(pluginId) keeps returning null.
Expected
bar.shell.serviceFor(pluginId) should return the live service instance for a plugin's own service (same id in both manifest.entryPoints.service and the widget's own serviceFor() call), matching how _services[pluginId] is populated by shell.qml's ensureService/_syncServices.
Scope / reproducibility
This was reproduced independently on two unrelated third-party plugins installed on the same system (both declaring service + bar-widget kinds), both showing svc=N in the same session — so this doesn't look specific to one plugin's code, but to how bar.shell gets constructed for third-party service+bar-widget plugins (Bar.qml's pluginBarApiFor / shell.qml's pluginShellForId → scopedPluginShellForId → pluginShellFor → createScopedPluginShell → _serviceLookup → pluginServiceFor → pluginOwnsTarget/resolveEnabledId chain). A full omarchy restart shell (fresh process) did not clear the problem, so it isn't just a stale in-memory cache from a hot-reload.
System info
omarchy version: 4.0.3-1- Quickshell: 0.3.0 (revision 28771c7c74b42e20afca0b1b63980cb46515537c, AUR quickshell-git)
- Hyprland: 0.56.2 (v0.56.2, commit efb50993780079460b0cbed1363e2166a2de1d9f)
View raw text
## What happened
For a third-party plugin that declares both `"service"` and `"bar-widget"` kinds in its manifest, the bar-widget's `bar.shell.serviceFor(pluginId)` call reliably returns `null`, even though:
- the service itself loads and runs correctly (its own IPC target responds, and it persists state to disk correctly)
- `bar.shell` exists and `bar.shell.serviceFor` is a genuine function (not missing/undefined)
Since a plugin's `BarWidget.qml`/`Panel.qml` typically guard every interactive control with `if (!svc) return`, this makes every button, tab, toggle, and slider in the plugin's popup a silent no-op — the popup opens and displays correctly (since static labels don't need `svc`), but nothing in it does anything, and slider drags visually "snap back" after release (because the value binding re-reads from the unchanged service state).
## Steps to reproduce
1. Install a plugin whose `manifest.json` has:
```json
"kinds": ["service", "bar-widget"],
"entryPoints": { "service": "Service.qml", "barWidget": "BarWidget.qml" }
```
2. In `BarWidget.qml`, add a diagnostic to confirm the failure, e.g. in a `tooltipText`:
```qml
tooltipText: "bar=" + (root.bar ? "Y" : "N")
+ " shell=" + (root.bar && root.bar.shell ? "Y" : "N")
+ " serviceForFn=" + (root.bar && root.bar.shell && typeof root.bar.shell.serviceFor === "function" ? "Y" : "N")
+ " svc=" + (root.svc ? "Y" : "N")
```
where `svc` is `bar && bar.shell ? bar.shell.serviceFor(pluginId) : null`.
3. Restart the shell (`omarchy restart shell`) and hover the widget's bar icon.
## Observed
`bar=Y shell=Y serviceForFn=Y svc=N` — the lookup function exists and is callable, but returns null.
Confirmed independently that the service itself is alive and controllable the whole time, e.g.:
```
quickshell -p /usr/share/omarchy/shell ipc call <service-ipc-target> <method> <args>
```
correctly mutates and persists the plugin's own state file, while the widget's `bar.shell.serviceFor(pluginId)` keeps returning null.
## Expected
`bar.shell.serviceFor(pluginId)` should return the live service instance for a plugin's own service (same `id` in both `manifest.entryPoints.service` and the widget's own `serviceFor()` call), matching how `_services[pluginId]` is populated by `shell.qml`'s `ensureService`/`_syncServices`.
## Scope / reproducibility
This was reproduced independently on **two unrelated third-party plugins** installed on the same system (both declaring `service` + `bar-widget` kinds), both showing `svc=N` in the same session — so this doesn't look specific to one plugin's code, but to how `bar.shell` gets constructed for third-party service+bar-widget plugins (`Bar.qml`'s `pluginBarApiFor` / `shell.qml`'s `pluginShellForId` → `scopedPluginShellForId` → `pluginShellFor` → `createScopedPluginShell` → `_serviceLookup` → `pluginServiceFor` → `pluginOwnsTarget`/`resolveEnabledId` chain). A full `omarchy restart shell` (fresh process) did not clear the problem, so it isn't just a stale in-memory cache from a hot-reload.
## System info
- `omarchy version`: 4.0.3-1
- Quickshell: 0.3.0 (revision 28771c7c74b42e20afca0b1b63980cb46515537c, AUR quickshell-git)
- Hyprland: 0.56.2 (v0.56.2, commit efb50993780079460b0cbed1363e2166a2de1d9f)
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.
- Out of scopeDecided by agents · verified · 2026-10-09 13:28 UTC