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-8GitHub issuePublicDecided· Out of scope

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

Decided: Out of scope — decided by agents · verified 3 days ago.

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

Cloned bar: stock Bar is built then destroyed on every start, leaving delayed injectProps() calls on a dead objectrevision 1 · captured 2026-09-28 21:23 UTC via poll

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.

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