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

Notification image-path hint bypasses icon resolution, rendering Qt's missing-texture placeholder for themed icon names

Reported by MyGuyArrow · filed Sep 3, 2026Closed upstream on 2026-10-11 by the bot omarchybot, as a duplicate (target not recorded).

Decided: Out of scope — decided by agents · verified 5 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

Notification image-path hint bypasses icon resolution, rendering Qt's missing-texture placeholder for themed icon namesrevision 1 · captured 2026-09-28 21:24 UTC via poll

What happened

A notification whose icon arrives via the `image-path` hint as a themed icon name renders Qt's magenta/black missing-texture placeholder in the icon slot.

This is the path notify-send -i <name> takes: libnotify puts the name in the image-path hint and leaves app_icon empty, so it affects any sender using notify-send with a themed name.

Steps to reproduce

notify-send -i definitely-not-an-installed-icon "Notification icon test" "Icon name is not in the icon theme"

Expected

The icon slot is hidden, exactly as shell/plugins/notifications/components/NotificationCard.qml:116-118 intends:

Hide the slot when the icon failed to resolve (themed-icon name not in the user's icon theme) AND we don't have a glyph fallback — prevents rendering Qt's pink broken-image placeholder.

Actual

A magenta/black checkerboard is drawn in the icon slot.

Cause

NotificationCard.qml:39:

readonly property string smallIconSource: image.length > 0 ? image : iconSource(appIcon)

iconSource() (line 58) is what resolves themed names and check-guards them:

function iconSource(icon) {
  var value = String(icon || "")
  if (value.length === 0) return ""
  if (value.indexOf("file://") === 0 || value.indexOf("image://") === 0) return value
  if (value.charAt(0) === "/") return Util.fileUrl(value)
  return Quickshell.iconPath(value, true)   // check flag -> "" when missing
}

…but it is only applied to appIcon. image goes straight to Image.source, so a bare themed name is treated as a relative URL, fails to load, and Qt paints its placeholder. The slot's visibility guard doesn't suppress it because hasSmallIcon is true (image.length > 0).

Per the Desktop Notifications Specification, image-path is "a URI … or a name in a freedesktop.org-compliant icon theme" — so it needs the same resolution as app_icon.

Confirmed the hint with dbus-monitor:

method call ... member=Notify
   string "notify-send"
   uint32 0
   string ""                     <- app_icon is empty
   string "DBUS probe"
   string "body"
   array [ ]
   array [
      dict entry(
         string "image-path"
         variant    string "definitely-not-an-installed-icon"
      )
      ...
   ]

In isolation Quickshell.iconPath("definitely-not-an-installed-icon", true) correctly returns "", so routing image through iconSource() looks sufficient:

readonly property string smallIconSource: image.length > 0 ? iconSource(image) : iconSource(appIcon)

Also observed — same symptom, different trigger

A bare `app_icon` name also produced the placeholder when the name was absent from a stale /usr/share/icons/hicolor/icon-theme.cache, even though the PNGs were on disk. Concretely: Ghostty relays terminal notifications tagged app_icon=com.mitchellh.ghostty, and every such toast (Claude Code's among them) showed the checkerboard. pkexec gtk-update-icon-cache -f -t /usr/share/icons/hicolor fixed that case.

The cache went stale because Arch's gtk-update-icon-cache.hook triggers on usr/share/icons/*/ but excludes usr/share/icons/*/?*, so it never fires when a package adds icons into an existing theme tree. That part is not an Omarchy bug — but the placeholder rendering on an unresolvable app_icon name is the same guard failing, and I could not fully isolate why iconPath's check flag didn't suppress it in that state. Flagging it in case the fix should also harden the appIcon branch.

System

Omarchy4.0.2-1
Quickshell0.3.1-1 (Arch)
qt6-base6.11.2-2
CPUIntel Core Ultra 9 185H
GPUIntel Arc (Meteor Lake-P) + NVIDIA RTX 4070 Max-Q
Icon themeYaru-sage-dark
Display scale2
View raw text
### What happened

A notification whose icon arrives via the **`image-path` hint** as a *themed icon name* renders Qt's magenta/black missing-texture placeholder in the icon slot.

This is the path `notify-send -i <name>` takes: libnotify puts the name in the `image-path` hint and leaves `app_icon` empty, so it affects any sender using `notify-send` with a themed name.

### Steps to reproduce

```bash
notify-send -i definitely-not-an-installed-icon "Notification icon test" "Icon name is not in the icon theme"
```

### Expected

The icon slot is hidden, exactly as `shell/plugins/notifications/components/NotificationCard.qml:116-118` intends:

> Hide the slot when the icon failed to resolve (themed-icon name not in the user's icon theme) AND we don't have a glyph fallback — prevents rendering Qt's pink broken-image placeholder.

### Actual

A magenta/black checkerboard is drawn in the icon slot.

### Cause

`NotificationCard.qml:39`:

```qml
readonly property string smallIconSource: image.length > 0 ? image : iconSource(appIcon)
```

`iconSource()` (line 58) is what resolves themed names and check-guards them:

```qml
function iconSource(icon) {
  var value = String(icon || "")
  if (value.length === 0) return ""
  if (value.indexOf("file://") === 0 || value.indexOf("image://") === 0) return value
  if (value.charAt(0) === "/") return Util.fileUrl(value)
  return Quickshell.iconPath(value, true)   // check flag -> "" when missing
}
```

…but it is only applied to `appIcon`. `image` goes straight to `Image.source`, so a bare themed name is treated as a relative URL, fails to load, and Qt paints its placeholder. The slot's visibility guard doesn't suppress it because `hasSmallIcon` is true (`image.length > 0`).

Per the [Desktop Notifications Specification](https://specifications.freedesktop.org/notification-spec/latest/hints.html), `image-path` is *"a URI … or a name in a freedesktop.org-compliant icon theme"* — so it needs the same resolution as `app_icon`.

Confirmed the hint with `dbus-monitor`:

```
method call ... member=Notify
   string "notify-send"
   uint32 0
   string ""                     <- app_icon is empty
   string "DBUS probe"
   string "body"
   array [ ]
   array [
      dict entry(
         string "image-path"
         variant    string "definitely-not-an-installed-icon"
      )
      ...
   ]
```

In isolation `Quickshell.iconPath("definitely-not-an-installed-icon", true)` correctly returns `""`, so routing `image` through `iconSource()` looks sufficient:

```qml
readonly property string smallIconSource: image.length > 0 ? iconSource(image) : iconSource(appIcon)
```

### Also observed — same symptom, different trigger

A bare **`app_icon`** name also produced the placeholder when the name was absent from a stale `/usr/share/icons/hicolor/icon-theme.cache`, even though the PNGs were on disk. Concretely: Ghostty relays terminal notifications tagged `app_icon=com.mitchellh.ghostty`, and every such toast (Claude Code's among them) showed the checkerboard. `pkexec gtk-update-icon-cache -f -t /usr/share/icons/hicolor` fixed that case.

The cache went stale because Arch's `gtk-update-icon-cache.hook` triggers on `usr/share/icons/*/` but excludes `usr/share/icons/*/?*`, so it never fires when a package adds icons into an existing theme tree. That part is not an Omarchy bug — but the placeholder rendering on an unresolvable `app_icon` name is the same guard failing, and I could not fully isolate why `iconPath`'s check flag didn't suppress it in that state. Flagging it in case the fix should also harden the `appIcon` branch.

### System

| | |
|---|---|
| Omarchy | 4.0.2-1 |
| Quickshell | 0.3.1-1 (Arch) |
| qt6-base | 6.11.2-2 |
| CPU | Intel Core Ultra 9 185H |
| GPU | Intel Arc (Meteor Lake-P) + NVIDIA RTX 4070 Max-Q |
| Icon theme | Yaru-sage-dark |
| Display scale | 2 |

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 10:38 UTC