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 bar: stock Bar is built then destroyed on every start, leaving delayed injectProps() calls on a dead object
Reported by nnyrron13 · filed Sep 28, 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
With a cloned bar active (omarchy plugin clone omarchy.bar → nnyrron.bar inshell.json), every shell start logs this four times:
WARN scene: QML IpcHandler at @plugins/bar/Bar.qml[1185:3]: Handler was registered
but will not be used because another handler is registered for target omarchy.bar
WARN: QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context
WARN scene: @plugins/bar/Bar.qml[2003:-1]: TypeError: Property 'pluginBarApiFor' of
object Bar_QMLTYPE_18(0x7c6a5082b860) is not a function (exception occurred during
delayed function evaluation)All four TypeErrors name the same object pointer, so it is one Bar instance
receiving four queued calls, not four separate faults.
Why it happens
pluginBarApiFor is defined at plugins/bar/Bar.qml:229, top-level in the same
file that fails to find it, and there is only one id: root in the file — so it
is not shadowing. The preceding QQmlVMEMetaObject ... invalid context is the
tell: the object's VME meta-object is gone, so every QML-declared function on
it reads as missing.
The instance is a transient stock Bar, built and destroyed during startup:
shell.qml:184—activeBarIdis
selectedBarId !== failedBarId && selectedBarAvailable ? selectedBarId : defaultBarId.
Before the plugin registry has scanned, selectedBarAvailable is false, so
activeBarId falls back to omarchy.bar.
2. That makes defaultBarLoader (shell.qml:244, active: shell.activeBarId === shell.defaultBarId)
active, and the stock Bar is constructed. Its IpcHandler registration is the
giveaway — that is the target omarchy.bar warning above, logged immediately
before the TypeErrors.
3. The registry resolves the cloned bar, activeBarId flips, the loader goes
inactive and the stock Bar is destroyed.
4. Four injectProps() calls queued in step 2 evaluate afterwards against the
destroyed object and throw at line 2003:
target.bar = firstParty ? root : root.pluginBarApiFor(pluginApiId, moduleName, registered).
So the stock bar is built speculatively on every start purely because the
registry has not scanned yet, then thrown away.
Expected
No bar constructed for an id that is about to be replaced, and no delayed call
evaluating against a destroyed object.
Two possible fixes, which address different halves:
- Gate
defaultBarLoader.activeon the registry having scanned, soactiveBarId
does not transiently report omarchy.bar while the configured bar is merely
not yet discovered. This removes the wasted construction.
- Guard the delayed evaluation in injectProps() against a torn-down root.
This only silences the symptom.
Impact
Cosmetic as far as I can tell — the surviving bar is the clone and it works. The
cost is one wasted Bar construction and eight log lines per start. It is
reproducible for anyone running a cloned or third-party bar, and the noise makes
the shell log harder to read when debugging one's own QML.
Related
injectProps() is also the site of #13011, which reports a different throw one
line later (line 2004, "Cannot assign to read-only property moduleName"). Same
function, adjacent line, different cause — filing separately rather than as a
duplicate. Possibly of interest together, since #13011 suspects its TypeErrors of
putting delegate-model incubation into the state that then segfaulted.
Steps to reproduce
omarchy plugin clone omarchy.bar- Ensure
shell.json'sbar.idis the clone. omarchy restart shelljournalctl --user -t omarchy-shell -e— the four TypeErrors are there, right
after the target omarchy.bar IpcHandler warning.
Environment
- omarchy 4.0.4-1
- quickshell 0.3.1-1
- qt6-declarative 6.11.2-1, qt6-base 6.11.2-3
- Arch Linux, kernel 7.2.5-3-omarchy
- Two monitors (the four calls are one object, so this does not look monitor-related)
Filed by Claude Opus 5 via Claude Code.
View raw text
## What happened With a cloned bar active (`omarchy plugin clone omarchy.bar` → `nnyrron.bar` in `shell.json`), every shell start logs this four times: ``` WARN scene: QML IpcHandler at @plugins/bar/Bar.qml[1185:3]: Handler was registered but will not be used because another handler is registered for target omarchy.bar WARN: QQmlVMEMetaObject: Internal error - attempted to evaluate a function in an invalid context WARN scene: @plugins/bar/Bar.qml[2003:-1]: TypeError: Property 'pluginBarApiFor' of object Bar_QMLTYPE_18(0x7c6a5082b860) is not a function (exception occurred during delayed function evaluation) ``` All four TypeErrors name the **same object pointer**, so it is one Bar instance receiving four queued calls, not four separate faults. ## Why it happens `pluginBarApiFor` is defined at `plugins/bar/Bar.qml:229`, top-level in the same file that fails to find it, and there is only one `id: root` in the file — so it is not shadowing. The preceding `QQmlVMEMetaObject ... invalid context` is the tell: the object's VME meta-object is gone, so *every* QML-declared function on it reads as missing. The instance is a **transient stock Bar**, built and destroyed during startup: 1. `shell.qml:184` — `activeBarId` is `selectedBarId !== failedBarId && selectedBarAvailable ? selectedBarId : defaultBarId`. Before the plugin registry has scanned, `selectedBarAvailable` is false, so `activeBarId` falls back to `omarchy.bar`. 2. That makes `defaultBarLoader` (`shell.qml:244`, `active: shell.activeBarId === shell.defaultBarId`) active, and the stock Bar is constructed. Its IpcHandler registration is the giveaway — that is the `target omarchy.bar` warning above, logged immediately before the TypeErrors. 3. The registry resolves the cloned bar, `activeBarId` flips, the loader goes inactive and the stock Bar is destroyed. 4. Four `injectProps()` calls queued in step 2 evaluate afterwards against the destroyed object and throw at line 2003: `target.bar = firstParty ? root : root.pluginBarApiFor(pluginApiId, moduleName, registered)`. So the stock bar is built speculatively on every start purely because the registry has not scanned yet, then thrown away. ## Expected No bar constructed for an id that is about to be replaced, and no delayed call evaluating against a destroyed object. Two possible fixes, which address different halves: - Gate `defaultBarLoader.active` on the registry having scanned, so `activeBarId` does not transiently report `omarchy.bar` while the configured bar is merely not yet discovered. This removes the wasted construction. - Guard the delayed evaluation in `injectProps()` against a torn-down `root`. This only silences the symptom. ## Impact Cosmetic as far as I can tell — the surviving bar is the clone and it works. The cost is one wasted Bar construction and eight log lines per start. It is reproducible for anyone running a cloned or third-party bar, and the noise makes the shell log harder to read when debugging one's own QML. ## Related `injectProps()` is also the site of #13011, which reports a *different* throw one line later (line 2004, "Cannot assign to read-only property moduleName"). Same function, adjacent line, different cause — filing separately rather than as a duplicate. Possibly of interest together, since #13011 suspects its TypeErrors of putting delegate-model incubation into the state that then segfaulted. ## Steps to reproduce 1. `omarchy plugin clone omarchy.bar` 2. Ensure `shell.json`'s `bar.id` is the clone. 3. `omarchy restart shell` 4. `journalctl --user -t omarchy-shell -e` — the four TypeErrors are there, right after the `target omarchy.bar` IpcHandler warning. ## Environment - omarchy 4.0.4-1 - quickshell 0.3.1-1 - qt6-declarative 6.11.2-1, qt6-base 6.11.2-3 - Arch Linux, kernel 7.2.5-3-omarchy - Two monitors (the four calls are one object, so this does not look monitor-related) Filed by Claude Opus 5 via Claude Code.
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 20:03 UTC