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.
bt-agent.service ExecCondition races bluetooth.service from the user manager, skipping the pairing agent for the whole boot
Reported by luizbafilho · filed Aug 29, 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
Note: issue reported by AI.
System details
- CPU: Intel Core i7-8700K
- GPU: Intel CoffeeLake-S GT2 [UHD Graphics 630]
- Omarchy: 4.0.0-1
- Architecture: x86_64
- Kernel: 7.1.8-arch1-3
omarchy-settings: 4.0.0-1systemd: 261.2-1- BlueZ: 5.87-2 (
bluez,bluez-utils) bluez-tools: 0.2.0-6 (so/usr/bin/bt-agentis present — this is not #6992)
What's wrong?
bt-agent.service gates its startup on a system unit from a user unit:
# /usr/lib/systemd/user/bt-agent.service (omarchy-settings 4.0.0-1)
ExecCondition=/usr/bin/systemctl is-active --quiet bluetooth.service
WantedBy=graphical-session.targetsystemd has no cross-manager ordering, so a user unit cannot order itself
after a system unit — there is no After=bluetooth.service that would work
here. The unit's only ordering is After=dbus.socket, which does not help.
The ExecCondition therefore races the system manager.
When the user session reaches graphical-session.target before the system
manager reaches bluetooth.service, the condition fails and the agent is
skipped for the entire boot. Two things make this unrecoverable:
- An
ExecConditionfailure is a clean skip, not a failure, so
Restart=on-failure never fires.
2. Nothing retriggers the unit when Bluetooth becomes available moments later.
With no agent registered, bluetoothd refuses every pairing that needs
confirmation:
bluetoothd[2194]: src/device.c:new_auth() No agent available for request type 2
bluetoothd[2194]: device_confirm_passkey: Operation not permittedThe device retries several times a second, so the user sees a device flapping
connect/disconnect forever, with no error surfaced anywhere in the GUI.
Evidence that it is a race
Same machine, no config changes between boots. The agent starts iff its
condition happens to run after bluetooth.service:
| Boot | bluetooth.service Started | bt-agent condition evaluated | Result |
|---|---|---|---|
| Aug 15 14:30 | 14:30:42 | after | started 14:30:44 |
| Aug 15 17:50 | 17:50:46 | after | started 17:50:48 |
| Aug 23 08:54 | 08:54:20 | 08:54:18 (2s early) | skipped |
| Aug 29 12:26 | 12:26:11 | 12:26:08 (3s early) | skipped |
Failing boot:
Aug 29 12:26:08 systemd[1055]: Starting Bluetooth pairing agent (auto-accept)...
Aug 29 12:26:08 systemd[1055]: bt-agent.service: Skipped due to 'exec-condition'.
Aug 29 12:26:08 systemd[1055]: Condition check resulted in Bluetooth pairing agent (auto-accept) being skipped.
Aug 29 12:26:11 systemd[1]: Started Bluetooth service.$ systemctl --user status bt-agent.service
Active: inactive (dead) (Result: exec-condition)
Condition: start condition unmet
Process: 1141 ExecCondition=/usr/bin/systemctl is-active --quiet bluetooth.service (code=exited, status=3)Steps to reproduce
- Boot a machine where the user session wins the race (readily reproducible on
fast NVMe systems; it reproduced on 2 of the last 4 boots here).
2. systemctl --user status bt-agent.service → Skipped due to 'exec-condition'.
3. Put any device requiring pairing confirmation (e.g. a Logitech BLE mouse)
into pairing mode and pair it from the Omarchy Bluetooth panel.
4. Pairing never completes; the device flaps connect/disconnect; the journal
fills with No agent available for request type 2.
Expected result
The pairing agent is running whenever Bluetooth is available, so pairing works
on every boot rather than on a coin flip.
Actual result
Pairing is silently broken for the whole boot, with no indication in the GUI.
Why this is worth fixing beyond the obvious
Because it is timing-dependent, it presents as "Bluetooth pairing randomly
stops working", which is very hard to attribute. It also makes other Bluetooth
reports ambiguous — e.g. in #8485 bt-agent was running (its prompt appears
in that reporter's journal), whereas here it never started, yet the
user-visible symptom (device flapping, pairing never completes) looks similar.
It compounds with two existing issues: omarchy-bluetooth-device runsbluetoothctl pair one-shot with output to /dev/null and || true, then
runs trust unconditionally — so the failure is invisible and leaves devices
stuck at Trusted: yes / Paired: no (#7879), which then blocks retries until
the device is manually removed.
Suggested fix
Replace the racy check with one that waits rather than skipping. Something like:
[Service]
ExecCondition=
ExecStartPre=/bin/sh -c 'for i in $(seq 1 60); do systemctl is-active --quiet bluetooth.service && exit 0; sleep 1; done; exit 1'
Restart=on-failure
RestartSec=5This exits immediately (~5ms) when bluetooth.service is already up, so it
costs nothing on boots that currently work, and returns non-zero on timeout soRestart=on-failure genuinely applies — unlike ExecCondition.
The original intent of the ExecCondition (per #6992, avoiding a restart loop
on machines with no usable adapter) is preserved by bounding retries withStartLimitIntervalSec= / StartLimitBurst= rather than by skipping outright.
Workaround
A user drop-in at ~/.config/systemd/user/bt-agent.service.d/ with the above
fixes it locally without touching the packaged unit.
View raw text
_Note: issue reported by AI._
### System details
- CPU: Intel Core i7-8700K
- GPU: Intel CoffeeLake-S GT2 [UHD Graphics 630]
- Omarchy: 4.0.0-1
- Architecture: x86_64
- Kernel: 7.1.8-arch1-3
- `omarchy-settings`: 4.0.0-1
- `systemd`: 261.2-1
- BlueZ: 5.87-2 (`bluez`, `bluez-utils`)
- `bluez-tools`: 0.2.0-6 (so `/usr/bin/bt-agent` is present — this is **not** #6992)
### What's wrong?
`bt-agent.service` gates its startup on a **system** unit from a **user** unit:
```ini
# /usr/lib/systemd/user/bt-agent.service (omarchy-settings 4.0.0-1)
ExecCondition=/usr/bin/systemctl is-active --quiet bluetooth.service
WantedBy=graphical-session.target
```
systemd has no cross-manager ordering, so a user unit **cannot** order itself
after a system unit — there is no `After=bluetooth.service` that would work
here. The unit's only ordering is `After=dbus.socket`, which does not help.
The `ExecCondition` therefore races the system manager.
When the user session reaches `graphical-session.target` before the system
manager reaches `bluetooth.service`, the condition fails and the agent is
**skipped for the entire boot**. Two things make this unrecoverable:
1. An `ExecCondition` failure is a **clean skip, not a failure**, so
`Restart=on-failure` never fires.
2. Nothing retriggers the unit when Bluetooth becomes available moments later.
With no agent registered, `bluetoothd` refuses every pairing that needs
confirmation:
```text
bluetoothd[2194]: src/device.c:new_auth() No agent available for request type 2
bluetoothd[2194]: device_confirm_passkey: Operation not permitted
```
The device retries several times a second, so the user sees a device flapping
connect/disconnect forever, with no error surfaced anywhere in the GUI.
### Evidence that it is a race
Same machine, no config changes between boots. The agent starts iff its
condition happens to run *after* `bluetooth.service`:
| Boot | `bluetooth.service` Started | `bt-agent` condition evaluated | Result |
|------|------------------------------|-------------------------------|--------|
| Aug 15 14:30 | 14:30:42 | after | started 14:30:44 |
| Aug 15 17:50 | 17:50:46 | after | started 17:50:48 |
| Aug 23 08:54 | 08:54:20 | 08:54:18 (2s early) | **skipped** |
| Aug 29 12:26 | 12:26:11 | 12:26:08 (3s early) | **skipped** |
Failing boot:
```text
Aug 29 12:26:08 systemd[1055]: Starting Bluetooth pairing agent (auto-accept)...
Aug 29 12:26:08 systemd[1055]: bt-agent.service: Skipped due to 'exec-condition'.
Aug 29 12:26:08 systemd[1055]: Condition check resulted in Bluetooth pairing agent (auto-accept) being skipped.
Aug 29 12:26:11 systemd[1]: Started Bluetooth service.
```
```text
$ systemctl --user status bt-agent.service
Active: inactive (dead) (Result: exec-condition)
Condition: start condition unmet
Process: 1141 ExecCondition=/usr/bin/systemctl is-active --quiet bluetooth.service (code=exited, status=3)
```
### Steps to reproduce
1. Boot a machine where the user session wins the race (readily reproducible on
fast NVMe systems; it reproduced on 2 of the last 4 boots here).
2. `systemctl --user status bt-agent.service` → `Skipped due to 'exec-condition'`.
3. Put any device requiring pairing confirmation (e.g. a Logitech BLE mouse)
into pairing mode and pair it from the Omarchy Bluetooth panel.
4. Pairing never completes; the device flaps connect/disconnect; the journal
fills with `No agent available for request type 2`.
### Expected result
The pairing agent is running whenever Bluetooth is available, so pairing works
on every boot rather than on a coin flip.
### Actual result
Pairing is silently broken for the whole boot, with no indication in the GUI.
### Why this is worth fixing beyond the obvious
Because it is timing-dependent, it presents as "Bluetooth pairing randomly
stops working", which is very hard to attribute. It also makes other Bluetooth
reports ambiguous — e.g. in #8485 `bt-agent` *was* running (its prompt appears
in that reporter's journal), whereas here it never started, yet the
user-visible symptom (device flapping, pairing never completes) looks similar.
It compounds with two existing issues: `omarchy-bluetooth-device` runs
`bluetoothctl pair` one-shot with output to `/dev/null` and `|| true`, then
runs `trust` unconditionally — so the failure is invisible and leaves devices
stuck at `Trusted: yes / Paired: no` (#7879), which then blocks retries until
the device is manually `remove`d.
### Suggested fix
Replace the racy check with one that waits rather than skipping. Something like:
```ini
[Service]
ExecCondition=
ExecStartPre=/bin/sh -c 'for i in $(seq 1 60); do systemctl is-active --quiet bluetooth.service && exit 0; sleep 1; done; exit 1'
Restart=on-failure
RestartSec=5
```
This exits immediately (~5ms) when `bluetooth.service` is already up, so it
costs nothing on boots that currently work, and returns non-zero on timeout so
`Restart=on-failure` genuinely applies — unlike `ExecCondition`.
The original intent of the `ExecCondition` (per #6992, avoiding a restart loop
on machines with no usable adapter) is preserved by bounding retries with
`StartLimitIntervalSec=` / `StartLimitBurst=` rather than by skipping outright.
### Workaround
A user drop-in at `~/.config/systemd/user/bt-agent.service.d/` with the above
fixes it locally without touching the packaged unit.
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 09:57 UTC