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.
Lock screen: one unreachable fprintd-list probe disables fingerprint for the rest of the lock
Reported by osborng · filed Aug 31, 2026Closed upstream on 2026-10-04 by commit 879d6583dace (closed by dhh). GitHub close reason: completed.
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?
- Not yet mapped to any requirement or component.
- 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. No decision has been recorded yet.
Original report
What happens
fingerprintCheckProc in shell/plugins/lock/Service.qml decides whether fingerprint unlock is available by shelling out to fprintd-list, and collapses every non-matching result into "not configured":
command: ["bash", "-c", "if [[ -f /etc/pam.d/omarchy-lock-fingerprint ]] && command -v fprintd-list >/dev/null 2>&1 && fprintd-list \"$USER\" 2>/dev/null | grep -qi finger; then echo yes; else echo no; fi"]
...
onExited: {
root.fingerprintConfigured = String(fingerprintCheckStdout.text || "").trim() === "yes"
if (root.lockRequested && root.fingerprintConfigured) root.startFingerprint()
else if (!root.fingerprintConfigured && fingerprintPam.active) fingerprintPam.abort()
}But "the probe did not return an enrolled print" and "this user has no fingerprint configured" are not the same thing. The probe also fails when fprintd is momentarily unreachable — and then:
fingerprintConfiguredgoes false,- any in-flight fingerprint PAM session is aborted,
handleFingerprintFinishedonly re-armsfingerprintRetryTimerif (fingerprintConfigured), so the retry loop never runs again, and- nothing re-probes:
refreshFingerprintStatus()is only called frombeginLock().
So a single transient miss disables fingerprint unlock for the entire lock session, not for one attempt. The user gets no prompt and no indication why; the only way out is the password, and it stays broken until the next lock.
When it fires
The reliable trigger is the resume window. fprintd is D-Bus activated, and an activation request made while the daemon is stopping or while systemd is still working through the resume can simply fail:
Impossible to get devices: GDBus.Error:org.freedesktop.DBus.Error.NameHasNoOwner:
Could not activate remote peer 'net.reactivated.Fprint': activation request failedfprintd-list prints that to stdout, it contains no enrolled-print line, so the probe answers "no" and fingerprint is switched off for the lock.
Observed here on 4.0.2 after a lid-close suspend (a local resume hook was installed, so this timeline is context rather than a stock repro — the deterministic repro below is stock):
14:49:37 resume; fprintd stopped
14:49:38 quickshell.service.pam.subprocess: Starting pam session ... "omarchy-lock-fingerprint"
(no "Place your right index finger" prompt is ever relayed)
(fprintd is never activated — no "Starting Fingerprint Authentication Daemon")
(no further fingerprint PAM sessions at all)
14:49:51 unlocked via omarchy-lock-passwordSteps to reproduce
Observed on stock 4.0.2 (omarchy.lock enabled, no local patches to the plugin).
- Enrol a fingerprint and confirm fingerprint unlock works on the lock screen.
- Make fprintd unreachable, the way the resume window does:
sudo systemctl mask fprintd && sudo systemctl stop fprintd
3. Lock the screen. No fingerprint prompt — expected so far.
4. Restore fprintd while still locked: sudo systemctl unmask fprintd
5. Wait, still locked. Fingerprint never returns.
Measured run: fprintd restored at 20:19:52.785, session stayed locked until 20:20:17.096 — 24.3 seconds locked with a healthy, reachable daemon, and in that window:
fingerprint prompts relayed: 0
fprintd D-Bus activations: 0
fingerprint PAM sessions started: 0Unlock with the password, lock again, and fingerprint works immediately — the reader was fine the whole time. Two shorter runs (2.4s and 4.6s of healthy-but-locked time) behaved identically.
Step 5 is the bug: the reader is healthy and available, and the lock screen has permanently written it off for that session.
Expected
A probe that could not reach fprintd should be treated as "unknown", not as "not configured" — retried, not made terminal. Only a definitive answer from fprintd (or missing PAM config / missing fprintd-list) should disable fingerprint for the session.
Suggested fix
Make the probe three-state — yes / no / unknown — and on unknown keep the previous value and re-probe on a short bounded timer instead of tearing fingerprint down.
Two details that matter if anyone implements this:
- Key the decision on `fprintd-list`'s output, not its exit status. On fprintd 1.94.5-2 it returns 0 and 1 inconsistently for identical input (seen on a user with no prints), so a flaky
1would strand a perfectly good reader — a worse failure than the one being fixed. The unreachable case is recognisable from stdout (Could not activate remote peer ...), and the "definitely nothing enrolled" case fromhas no fingers enrolled. - Bound the retries (10 x 1s is plenty for the resume window) so a genuinely broken fprintd cannot spin for the life of the lock, and keep the interval clear of the 250ms
fingerprintRetryTimerso this does not add a second tight loop.
I am running a patched clone of the plugin along these lines. With it, step 4 above recovers inside the same lock:
20:09:06.154 fingerprint-probe-unavailable: retry 1/10
20:09:07.694 fingerprint-probe-unavailable: retry 2/10
20:09:08.702 fingerprint-probe-unavailable: retry 3/10
20:09:09.712 fingerprint-probe-unavailable: retry 4/10
Starting Fingerprint Authentication Daemon...
Starting pam session ... "omarchy-lock-fingerprint"
Relaying pam message: "Place your right index finger on the fingerprint reader"Happy to open a PR if the approach looks right.
Related
- #7176 (retry pacing) and #7229 (the suspend wedge) are adjacent but different: both are about attempts that reach a struggling reader. This one is upstream of that — the loop is switched off before any attempt is made.
- PR #7158 changes this probe's match to
grep -q ' - #', which correctly fixes a separate false-positive in the current expression (grep -qi fingeralso matcheshas no fingers enrolledand the device nameGoodix MOC Fingerprint Sensor, so an unenrolled user currently reads as configured). That PR does not change the terminalfingerprintConfigured = ... === "yes"behaviour reported here; I have left a note on it.
Environment
| Omarchy | 4.0.2-1 |
| Quickshell | 0.3.1-1 |
| fprintd | 1.94.5-2 |
| libfprint | 1.94.100-1 |
| Kernel | 7.1.9-arch1-2 |
| Reader | Goodix 27c6:609c (Goodix MOC Fingerprint Sensor, press) |
View raw text
### What happens
`fingerprintCheckProc` in `shell/plugins/lock/Service.qml` decides whether fingerprint unlock is available by shelling out to `fprintd-list`, and collapses every non-matching result into "not configured":
```qml
command: ["bash", "-c", "if [[ -f /etc/pam.d/omarchy-lock-fingerprint ]] && command -v fprintd-list >/dev/null 2>&1 && fprintd-list \"$USER\" 2>/dev/null | grep -qi finger; then echo yes; else echo no; fi"]
...
onExited: {
root.fingerprintConfigured = String(fingerprintCheckStdout.text || "").trim() === "yes"
if (root.lockRequested && root.fingerprintConfigured) root.startFingerprint()
else if (!root.fingerprintConfigured && fingerprintPam.active) fingerprintPam.abort()
}
```
But "the probe did not return an enrolled print" and "this user has no fingerprint configured" are not the same thing. The probe also fails when fprintd is momentarily **unreachable** — and then:
- `fingerprintConfigured` goes false,
- any in-flight fingerprint PAM session is aborted,
- `handleFingerprintFinished` only re-arms `fingerprintRetryTimer` `if (fingerprintConfigured)`, so **the retry loop never runs again**, and
- nothing re-probes: `refreshFingerprintStatus()` is only called from `beginLock()`.
So a single transient miss disables fingerprint unlock **for the entire lock session**, not for one attempt. The user gets no prompt and no indication why; the only way out is the password, and it stays broken until the next lock.
### When it fires
The reliable trigger is the resume window. `fprintd` is D-Bus activated, and an activation request made while the daemon is stopping or while systemd is still working through the resume can simply fail:
```
Impossible to get devices: GDBus.Error:org.freedesktop.DBus.Error.NameHasNoOwner:
Could not activate remote peer 'net.reactivated.Fprint': activation request failed
```
`fprintd-list` prints that to stdout, it contains no enrolled-print line, so the probe answers "no" and fingerprint is switched off for the lock.
Observed here on 4.0.2 after a lid-close suspend (a local resume hook was installed, so this timeline is context rather than a stock repro — the deterministic repro below is stock):
```
14:49:37 resume; fprintd stopped
14:49:38 quickshell.service.pam.subprocess: Starting pam session ... "omarchy-lock-fingerprint"
(no "Place your right index finger" prompt is ever relayed)
(fprintd is never activated — no "Starting Fingerprint Authentication Daemon")
(no further fingerprint PAM sessions at all)
14:49:51 unlocked via omarchy-lock-password
```
### Steps to reproduce
Observed on stock 4.0.2 (`omarchy.lock` enabled, no local patches to the plugin).
1. Enrol a fingerprint and confirm fingerprint unlock works on the lock screen.
2. Make fprintd unreachable, the way the resume window does:
`sudo systemctl mask fprintd && sudo systemctl stop fprintd`
3. Lock the screen. No fingerprint prompt — expected so far.
4. Restore fprintd **while still locked**: `sudo systemctl unmask fprintd`
5. Wait, still locked. Fingerprint never returns.
Measured run: fprintd restored at 20:19:52.785, session stayed locked until 20:20:17.096 — **24.3 seconds locked with a healthy, reachable daemon**, and in that window:
```
fingerprint prompts relayed: 0
fprintd D-Bus activations: 0
fingerprint PAM sessions started: 0
```
Unlock with the password, lock again, and fingerprint works immediately — the reader was fine the whole time. Two shorter runs (2.4s and 4.6s of healthy-but-locked time) behaved identically.
Step 5 is the bug: the reader is healthy and available, and the lock screen has permanently written it off for that session.
### Expected
A probe that could not reach fprintd should be treated as "unknown", not as "not configured" — retried, not made terminal. Only a definitive answer from fprintd (or missing PAM config / missing `fprintd-list`) should disable fingerprint for the session.
### Suggested fix
Make the probe three-state — `yes` / `no` / `unknown` — and on `unknown` keep the previous value and re-probe on a short bounded timer instead of tearing fingerprint down.
Two details that matter if anyone implements this:
- **Key the decision on `fprintd-list`'s output, not its exit status.** On fprintd 1.94.5-2 it returns 0 and 1 inconsistently for identical input (seen on a user with no prints), so a flaky `1` would strand a perfectly good reader — a worse failure than the one being fixed. The unreachable case is recognisable from stdout (`Could not activate remote peer ...`), and the "definitely nothing enrolled" case from `has no fingers enrolled`.
- Bound the retries (10 x 1s is plenty for the resume window) so a genuinely broken fprintd cannot spin for the life of the lock, and keep the interval clear of the 250ms `fingerprintRetryTimer` so this does not add a second tight loop.
I am running a patched clone of the plugin along these lines. With it, step 4 above recovers inside the same lock:
```
20:09:06.154 fingerprint-probe-unavailable: retry 1/10
20:09:07.694 fingerprint-probe-unavailable: retry 2/10
20:09:08.702 fingerprint-probe-unavailable: retry 3/10
20:09:09.712 fingerprint-probe-unavailable: retry 4/10
Starting Fingerprint Authentication Daemon...
Starting pam session ... "omarchy-lock-fingerprint"
Relaying pam message: "Place your right index finger on the fingerprint reader"
```
Happy to open a PR if the approach looks right.
### Related
- #7176 (retry pacing) and #7229 (the suspend wedge) are adjacent but different: both are about attempts that *reach* a struggling reader. This one is upstream of that — the loop is switched off before any attempt is made.
- PR #7158 changes this probe's match to `grep -q ' - #'`, which correctly fixes a separate false-positive in the current expression (`grep -qi finger` also matches `has no fingers enrolled` and the device name `Goodix MOC Fingerprint Sensor`, so an unenrolled user currently reads as configured). That PR does not change the terminal `fingerprintConfigured = ... === "yes"` behaviour reported here; I have left a note on it.
### Environment
| | |
|---|---|
| Omarchy | 4.0.2-1 |
| Quickshell | 0.3.1-1 |
| fprintd | 1.94.5-2 |
| libfprint | 1.94.100-1 |
| Kernel | 7.1.9-arch1-2 |
| Reader | Goodix 27c6:609c (`Goodix MOC Fingerprint Sensor`, press) |
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.
No decision has been recorded yet.