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-1075GitHub issuePublicFixed

Quickshell SIGABRT ("Tried to show lockscreen surfaces without active lock") when a plugin live-reloads while the screen is locked

Reported by ninepointlabs · filed Sep 2, 2026Closed upstream on 2026-10-09 by its own reporter ninepointlabs. GitHub close reason: completed. Closed by its own reporter — not by itself evidence of a fix.

In the audited area (lock) — decided by agents · verified. Not validated 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?
AreaIn the audited arealock· 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?
Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: in the audited area (lock) — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.

Original report

Quickshell SIGABRT ("Tried to show lockscreen surfaces without active lock") when a plugin live-reloads while the screen is lockedrevision 1 · captured 2026-09-28 21:24 UTC via poll

What happened

Quickshell (the Omarchy shell) crashes with SIGABRT when its QML scene is
live-reloaded (triggered by a local plugin file change) while the screen is
already locked. This is the third such crash in 9 days on this machine — same
failure signature each time.

Crash log (quickshell's own crash reporter, `~/.cache/quickshell/crashes/<id>/report.txt`):

FATAL: Tried to show lockscreen surfaces without active lock

That FATAL line is the last thing logged before abort(). The backtrace shows
the abort firing from inside QDebug::~QDebug() (Qt's qFatal mechanism),
reached through a QML property write on a QQmlTimer tick — i.e. one of
Omarchy's own lock-related timers. An earlier crash on this machine (Aug 24)
hit the identical code path with debug symbols intact, resolving to
WlSessionLock::updateSurfaces.

Trigger sequence (from journalctl, timestamps CDT)

  1. 13:58:09 — idle timeout locks the screen normally; secure=true at 13:58:10.
  2. 13:59:28 — Local plugin changed, reloading: nostr-signer — a file change

under a local plugin directory causes Omarchy to live-reload the entire
shell QML scene (confirmed by every other plugin's IpcHandler logging a
duplicate-registration warning immediately after, at 13:59:29).
3. The reload destroys and recreates the lock component
(plugins/lock/Service.qml) while the screen is still genuinely locked at
the Wayland protocol level. The recreated component has no memory of owning
a lock, so it treats the still-valid lock as "stranded" and calls
recoverStrandedLock() → beginLock(), requesting a second lock
(lock-stranded: recovering → lock-requested at 13:59:29).
4. That redundant re-lock races quickshell's own async lock-confirmation
handshake with the compositor. ~69 seconds later (14:00:38), quickshell
tries to show the lock surfaces before that handshake completes, and hits
its own fatal assertion.

The stranded-lock recovery logic in Service.qml (around
checkStrandedLock() / recoverStrandedLock()) is written for the case where
the quickshell process actually restarted and the compositor-side lock
outlived it — the code comment there explicitly says as much. It doesn't
appear to account for a **live QML scene reload within the same still-running
process**, where the lock was never actually orphaned.

What was expected

A plugin file change reloading the shell while the screen is locked should not
tear down and reacquire the session lock, and should never crash quickshell.

Steps to reproduce

  1. Lock the screen (idle timeout or manual lock).
  2. While locked, edit/touch a file under a local plugin in

~/.config/omarchy/plugins/<plugin>/ to trigger Omarchy's local-plugin
live-reload.
3. Wait roughly a minute. Quickshell aborts with SIGABRT and the log line
FATAL: Tried to show lockscreen surfaces without active lock.

This reproduced consistently enough to hit twice in 9 days on normal daily use
(Aug 24 and Sep 1) without deliberately trying to trigger it.

System details

$ omarchy version
4.0.2-1

omarchy debug --no-sudo --print is not available on this install
(Unknown Omarchy command), so I can't attach that output.

  • Quickshell: 0.3.1 (Arch Linux build), Qt 6.11.2
  • GPU: AMD (amdgpu), dual GPU (PCI 03:00.0 + 78:00.0)
  • Not caused by the Aug 25 quickshell 0.3.0→0.3.1 upgrade — the identical

failure reproduced on both versions.
- Not an OOM kill (14GB RAM, 8GB free at diagnosis time).
- No data loss — quickshell auto-restarts in under a second and its own
recovery logic re-secures the lock immediately after.

Coredump reference (this machine only, not attached)

PID: 3020510, Signal: SIGABRT, Time: 2026-09-01 14:00:38 CDT
Command: quickshell -n -p /usr/share/omarchy/shell

Filed by Claude Sonnet 5 via Claude Code.

View raw text
### What happened

Quickshell (the Omarchy shell) crashes with `SIGABRT` when its QML scene is
live-reloaded (triggered by a local plugin file change) while the screen is
already locked. This is the third such crash in 9 days on this machine — same
failure signature each time.

**Crash log (quickshell's own crash reporter, `~/.cache/quickshell/crashes/<id>/report.txt`):**
```
FATAL: Tried to show lockscreen surfaces without active lock
```
That FATAL line is the last thing logged before `abort()`. The backtrace shows
the abort firing from inside `QDebug::~QDebug()` (Qt's `qFatal` mechanism),
reached through a QML property write on a `QQmlTimer` tick — i.e. one of
Omarchy's own lock-related timers. An earlier crash on this machine (Aug 24)
hit the identical code path with debug symbols intact, resolving to
`WlSessionLock::updateSurfaces`.

### Trigger sequence (from journalctl, timestamps CDT)

1. `13:58:09` — idle timeout locks the screen normally; `secure=true` at `13:58:10`.
2. `13:59:28` — `Local plugin changed, reloading: nostr-signer` — a file change
   under a local plugin directory causes Omarchy to live-reload the **entire**
   shell QML scene (confirmed by every other plugin's `IpcHandler` logging a
   duplicate-registration warning immediately after, at `13:59:29`).
3. The reload destroys and recreates the lock component
   (`plugins/lock/Service.qml`) while the screen is still genuinely locked at
   the Wayland protocol level. The recreated component has no memory of owning
   a lock, so it treats the still-valid lock as "stranded" and calls
   `recoverStrandedLock()` → `beginLock()`, requesting a **second** lock
   (`lock-stranded: recovering` → `lock-requested` at `13:59:29`).
4. That redundant re-lock races quickshell's own async lock-confirmation
   handshake with the compositor. ~69 seconds later (`14:00:38`), quickshell
   tries to show the lock surfaces before that handshake completes, and hits
   its own fatal assertion.

The stranded-lock recovery logic in `Service.qml` (around
`checkStrandedLock()` / `recoverStrandedLock()`) is written for the case where
the quickshell *process* actually restarted and the compositor-side lock
outlived it — the code comment there explicitly says as much. It doesn't
appear to account for a **live QML scene reload within the same still-running
process**, where the lock was never actually orphaned.

### What was expected

A plugin file change reloading the shell while the screen is locked should not
tear down and reacquire the session lock, and should never crash quickshell.

### Steps to reproduce

1. Lock the screen (idle timeout or manual lock).
2. While locked, edit/touch a file under a local plugin in
   `~/.config/omarchy/plugins/<plugin>/` to trigger Omarchy's local-plugin
   live-reload.
3. Wait roughly a minute. Quickshell aborts with `SIGABRT` and the log line
   `FATAL: Tried to show lockscreen surfaces without active lock`.

This reproduced consistently enough to hit twice in 9 days on normal daily use
(Aug 24 and Sep 1) without deliberately trying to trigger it.

### System details

```
$ omarchy version
4.0.2-1
```

`omarchy debug --no-sudo --print` is not available on this install
(`Unknown Omarchy command`), so I can't attach that output.

- Quickshell: 0.3.1 (Arch Linux build), Qt 6.11.2
- GPU: AMD (amdgpu), dual GPU (PCI 03:00.0 + 78:00.0)
- Not caused by the Aug 25 quickshell 0.3.0→0.3.1 upgrade — the identical
  failure reproduced on both versions.
- Not an OOM kill (14GB RAM, 8GB free at diagnosis time).
- No data loss — quickshell auto-restarts in under a second and its own
  recovery logic re-secures the lock immediately after.

### Coredump reference (this machine only, not attached)

```
PID: 3020510, Signal: SIGABRT, Time: 2026-09-01 14:00:38 CDT
Command: quickshell -n -p /usr/share/omarchy/shell
```

---
Filed by Claude Sonnet 5 via Claude Code.

Also reported as

This defect is tracked under R-1075 (filed Sep 2, 2026). 4 other reports describe the same defect.

Earliest report of this defect: R-1147 (filed Aug 31, 2026).

  1. Sep 2, 2026R-1075 · this report— tracked here
  2. ·Decided by agents · verified

    Open upstream.

  3. ·Decided by agents · verified

    Open upstream.

  4. ·Decided by agents · verified

    Closed upstream on 2026-10-11 by the bot omarchybot, as a duplicate (target not recorded).

  5. ·Decided by agents · verified

    Open upstream.

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

  • Fixed bypr/7169· confirmed
  • Related PRpr/7572· confirmed
  • Fixed bypr/11240· confirmed

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.

  • Decided by agents · verified: in the audited area (lock)
  • Decided by agents · verified: matches no known issue

The outcome (valid, duplicate, not a bug, …) is not decided yet.