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.
powerprofilesctl crashes (SIGABRT) when power-profiles-daemon is masked — hit on every power event with TLP
Reported by ogrt · filed Aug 27, 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?
- 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: partly in the audited area (menu) — 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
Summary
powerprofilesctl (the Python CLI shipped with power-profiles-daemon) hard-crashes with SIGABRT when invoked while power-profiles-daemon.service is masked/inactive — e.g. on a TLP-managed setup, which is a common alternative to power-profiles-daemon on laptops. The crash is a Python interpreter-shutdown race (PyGILState_Ensure() called against an already-torn-down GIL from a GObject finalizer), not a clean error return, so it can't be handled by checking the exit code alone.
Several Omarchy Quickshell plugins call powerprofilesctl / omarchy-powerprofiles-set directly and hit this on every AC/battery transition and every time the power menu is opened.
Environment
- Omarchy 4.0.0-1 (
/usr/share/omarchy/version:4.0.0.alpha) - power-profiles-daemon 0.30-1 (installed but masked — TLP manages power instead)
- tlp 1.10.2-1
- Kernel 7.1.8-arch1-3
- Python 3.14.7
- CPU: Intel Core i7-7820HQ
Reproduction
- Mask
power-profiles-daemon.service(as recommended when using TLP instead):sudo systemctl mask power-profiles-daemon.service - Trigger any of:
- AC/battery power source change
- Opening the Omarchy menu's power-profile submenu
- Opening the Power bar widget/panel
powerprofilesctlcrashes with SIGABRT instead of failing cleanly.
Evidence
$ coredumpctl info 31765
PID: 31765 (powerprofilesct)
TID: 31805 (gdbus)
Signal: 6 (ABRT) si_code: SI_TKILL
Command Line: /bin/python3 /usr/bin/powerprofilesctl list
Executable: /usr/bin/python3.14
Stack trace of thread 31805:
#0 raise (libc.so.6)
#1 abort (libc.so.6)
#2 n/a (libpython3.14.so.1.0 + 0x1642ca)
#3 _Py_FatalErrorFunc (libpython3.14.so.1.0)
#4 PyEval_RestoreThread (libpython3.14.so.1.0)
#5 PyGILState_Ensure (libpython3.14.so.1.0)
#6 n/a (_gi.cpython-314-x86_64-linux-gnu.so + 0x1156e)
#7 n/a (libglib-2.0.so.0)
#8 g_object_unref (libgobject-2.0.so.0)
#9 n/a (libgio-2.0.so.0) [async D-Bus call teardown]
...PyGILState_Ensure() is being called from a PyGObject callback fired during object finalization/interpreter shutdown, after the GIL has already been destroyed — this is a known class of PyGObject/GLib async-D-Bus race, not something specific to this machine. When power-profiles-daemon isn't running, powerprofilesctl's D-Bus proxy setup takes a different (failing/retrying) code path, which appears to be what triggers the race here; against a live daemon it doesn't reproduce.
Affected call sites (upstream Omarchy source)
shell/plugins/panels/power/Panel.qml— profile-set action shells out toomarchy-powerprofiles-setshell/plugins/services/battery/Service.qml— callsomarchy-powerprofiles-seton every AC/battery transitionshell/plugins/menu/Menu.qml— power-profile submenu shells out topowerprofilesctl get/listto populate rows
None of these currently check whether power-profiles-daemon.service is actually active before invoking powerprofilesctl/omarchy-powerprofiles-set.
Proposed fix
Guard each call site with systemctl is-active --quiet power-profiles-daemon.service and skip the powerprofilesctl call entirely when it's masked/inactive, rather than letting it be invoked and crash. I have a working local patch that does this plus a best-effort fallback (deriving power-saver/balanced/performance from the CPU's own energy_performance_preference sysfs knob when no daemon is present) — happy to open a PR with it if that shape is welcome, or to split the guard-only fix from the EPP fallback if you'd rather review those separately.
Expected behavior
powerprofilesctl/omarchy-powerprofiles-set should not be invoked at all when power-profiles-daemon.service isn't active, so TLP-only setups don't hit this crash on every power event and menu open.
View raw text
## Summary
`powerprofilesctl` (the Python CLI shipped with `power-profiles-daemon`) hard-crashes with `SIGABRT` when invoked while `power-profiles-daemon.service` is masked/inactive — e.g. on a TLP-managed setup, which is a common alternative to `power-profiles-daemon` on laptops. The crash is a Python interpreter-shutdown race (`PyGILState_Ensure()` called against an already-torn-down GIL from a GObject finalizer), not a clean error return, so it can't be handled by checking the exit code alone.
Several Omarchy Quickshell plugins call `powerprofilesctl` / `omarchy-powerprofiles-set` directly and hit this on every AC/battery transition and every time the power menu is opened.
## Environment
- Omarchy 4.0.0-1 (`/usr/share/omarchy/version`: `4.0.0.alpha`)
- power-profiles-daemon 0.30-1 (installed but masked — TLP manages power instead)
- tlp 1.10.2-1
- Kernel 7.1.8-arch1-3
- Python 3.14.7
- CPU: Intel Core i7-7820HQ
## Reproduction
1. Mask `power-profiles-daemon.service` (as recommended when using TLP instead): `sudo systemctl mask power-profiles-daemon.service`
2. Trigger any of:
- AC/battery power source change
- Opening the Omarchy menu's power-profile submenu
- Opening the Power bar widget/panel
3. `powerprofilesctl` crashes with SIGABRT instead of failing cleanly.
## Evidence
```
$ coredumpctl info 31765
PID: 31765 (powerprofilesct)
TID: 31805 (gdbus)
Signal: 6 (ABRT) si_code: SI_TKILL
Command Line: /bin/python3 /usr/bin/powerprofilesctl list
Executable: /usr/bin/python3.14
Stack trace of thread 31805:
#0 raise (libc.so.6)
#1 abort (libc.so.6)
#2 n/a (libpython3.14.so.1.0 + 0x1642ca)
#3 _Py_FatalErrorFunc (libpython3.14.so.1.0)
#4 PyEval_RestoreThread (libpython3.14.so.1.0)
#5 PyGILState_Ensure (libpython3.14.so.1.0)
#6 n/a (_gi.cpython-314-x86_64-linux-gnu.so + 0x1156e)
#7 n/a (libglib-2.0.so.0)
#8 g_object_unref (libgobject-2.0.so.0)
#9 n/a (libgio-2.0.so.0) [async D-Bus call teardown]
...
```
`PyGILState_Ensure()` is being called from a PyGObject callback fired during object finalization/interpreter shutdown, after the GIL has already been destroyed — this is a known class of PyGObject/GLib async-D-Bus race, not something specific to this machine. When `power-profiles-daemon` isn't running, `powerprofilesctl`'s D-Bus proxy setup takes a different (failing/retrying) code path, which appears to be what triggers the race here; against a live daemon it doesn't reproduce.
## Affected call sites (upstream Omarchy source)
- `shell/plugins/panels/power/Panel.qml` — profile-set action shells out to `omarchy-powerprofiles-set`
- `shell/plugins/services/battery/Service.qml` — calls `omarchy-powerprofiles-set` on every AC/battery transition
- `shell/plugins/menu/Menu.qml` — power-profile submenu shells out to `powerprofilesctl get`/`list` to populate rows
None of these currently check whether `power-profiles-daemon.service` is actually active before invoking `powerprofilesctl`/`omarchy-powerprofiles-set`.
## Proposed fix
Guard each call site with `systemctl is-active --quiet power-profiles-daemon.service` and skip the `powerprofilesctl` call entirely when it's masked/inactive, rather than letting it be invoked and crash. I have a working local patch that does this plus a best-effort fallback (deriving power-saver/balanced/performance from the CPU's own `energy_performance_preference` sysfs knob when no daemon is present) — happy to open a PR with it if that shape is welcome, or to split the guard-only fix from the EPP fallback if you'd rather review those separately.
## Expected behavior
`powerprofilesctl`/`omarchy-powerprofiles-set` should not be invoked at all when `power-profiles-daemon.service` isn't active, so TLP-only setups don't hit this crash on every power event and menu open.
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/8712· confirmed
- Fixed bypr/12552· confirmed
- Related PRpr/5716· 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: partly in the audited area (menu)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.