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

Double-click on the Dictation indicator runs omarchy-restart-shell twice and segfaults quickshell in IpcHandler::updateRegistration

Reported by Ta-noshii · filed Sep 4, 2026 · open at source

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

Double-click on the Dictation indicator runs omarchy-restart-shell twice and segfaults quickshell in IpcHandler::updateRegistrationrevision 1 · captured 2026-09-28 21:24 UTC via poll

What happened

Pressing the bar's Dictation indicator twice within ~0.3 s launches omarchy-voxtype-config twice (Dictation.qml runs it from onPressed). Each run unconditionally calls omarchy-restart-shell after spawning the terminal, and omarchy-restart-shell has no guard against a concurrent instance. The first restart kills the old shell and launches a replacement; the second restart's quickshell kill loop finds that replacement ~270 ms into startup and kills it. Quickshell then segfaults while a plugin's IpcHandler registers against the already-destroyed engine generation.

Symbolized stack (Arch debuginfod, quickshell 0.3.1-1):

#5 __cxxabiv1::__dynamic_cast (src_type=EngineGenerationExt, dst_type=qs::io::ipc::IpcHandlerRegistry)
#6 qs::io::ipc::IpcHandler::updateRegistration  src/io/ipchandler.cpp:318
#7 qs::io::ipc::IpcHandler::onPostReload        src/io/ipchandler.cpp:278
#8 QQmlObjectCreator::finalize
#9 QQmlComponentPrivate::complete

Journal timeline, relative to the first omarchy-voxtype-config launch:

t (s)event
0.00xdg-terminal-exec ... voxtype configure launched (first press)
0.33same command launched again (second press)
2.11old shell: Exiting due to IPC request
2.38new shell: Launching config
2.65new shell: Exiting due to IPC request
2.78Quickshell has crashed (SIGSEGV), crashed within 10 seconds of launching. Not restarting
3.28second restart's launch comes up; the first launcher's retry logs An instance of this configuration is already running

The identical sequence (two voxtype configure launches 0.17 s apart, then the same IpcHandler::updateRegistration segfault) happened on this machine ten days earlier, so it is reproducible. No OOM, plenty of free memory, no package changes in between.

#8647 shows the same quickshell +0x16420b / +0x167713 offsets as an unexplained SIGSEGV "amid session-restart churn (shell exited twice via IPC requests in the preceding 5 s)"; that is this bug. #7076 describes a second omarchy-restart-shell racing the first without a crash.

Expected

Two presses on the Dictation indicator, or two overlapping omarchy-restart-shell calls, should not kill a shell that is still loading.

Steps to reproduce

  1. Have Voxtype installed so the Dictation indicator is in the bar.
  2. Double-click the indicator.
  3. Watch journalctl --user -t omarchy-shell -f: two Exiting due to IPC request lines ~0.5 s apart, the second within ~300 ms of Launching config, then the SIGSEGV.

Suggested fixes

  • Serialize omarchy-restart-shell (e.g. flock) so a concurrent call waits instead of killing the sibling's freshly launched shell.
  • omarchy-voxtype-config should not restart the shell unconditionally, or at least not until the terminal it spawned has exited.
  • Debounce onPressed in Dictation.qml.

The use-after-free itself (registering an IpcHandler against a destroyed EngineGenerationExt when an IPC kill lands mid-load) is upstream quickshell, but Omarchy's scripts create the condition.

System

Omarchy 4.0.1-1, quickshell 0.3.1-1, qt6-base 6.11.2-2, qt6-declarative 6.11.2-1, Hyprland.

Filed by Claude Fable 5.1 via Claude Code.

View raw text
## What happened

Pressing the bar's Dictation indicator twice within ~0.3 s launches `omarchy-voxtype-config` twice (`Dictation.qml` runs it from `onPressed`). Each run unconditionally calls `omarchy-restart-shell` after spawning the terminal, and `omarchy-restart-shell` has no guard against a concurrent instance. The first restart kills the old shell and launches a replacement; the second restart's `quickshell kill` loop finds that replacement ~270 ms into startup and kills it. Quickshell then segfaults while a plugin's `IpcHandler` registers against the already-destroyed engine generation.

Symbolized stack (Arch debuginfod, quickshell 0.3.1-1):

```
#5 __cxxabiv1::__dynamic_cast (src_type=EngineGenerationExt, dst_type=qs::io::ipc::IpcHandlerRegistry)
#6 qs::io::ipc::IpcHandler::updateRegistration  src/io/ipchandler.cpp:318
#7 qs::io::ipc::IpcHandler::onPostReload        src/io/ipchandler.cpp:278
#8 QQmlObjectCreator::finalize
#9 QQmlComponentPrivate::complete
```

Journal timeline, relative to the first `omarchy-voxtype-config` launch:

| t (s) | event |
|---|---|
| 0.00 | `xdg-terminal-exec ... voxtype configure` launched (first press) |
| 0.33 | same command launched again (second press) |
| 2.11 | old shell: `Exiting due to IPC request` |
| 2.38 | new shell: `Launching config` |
| 2.65 | new shell: `Exiting due to IPC request` |
| 2.78 | `Quickshell has crashed` (SIGSEGV), `crashed within 10 seconds of launching. Not restarting` |
| 3.28 | second restart's launch comes up; the first launcher's retry logs `An instance of this configuration is already running` |

The identical sequence (two `voxtype configure` launches 0.17 s apart, then the same `IpcHandler::updateRegistration` segfault) happened on this machine ten days earlier, so it is reproducible. No OOM, plenty of free memory, no package changes in between.

#8647 shows the same `quickshell +0x16420b` / `+0x167713` offsets as an unexplained SIGSEGV "amid session-restart churn (shell exited twice via IPC requests in the preceding 5 s)"; that is this bug. #7076 describes a second `omarchy-restart-shell` racing the first without a crash.

## Expected

Two presses on the Dictation indicator, or two overlapping `omarchy-restart-shell` calls, should not kill a shell that is still loading.

## Steps to reproduce

1. Have Voxtype installed so the Dictation indicator is in the bar.
2. Double-click the indicator.
3. Watch `journalctl --user -t omarchy-shell -f`: two `Exiting due to IPC request` lines ~0.5 s apart, the second within ~300 ms of `Launching config`, then the SIGSEGV.

## Suggested fixes

- Serialize `omarchy-restart-shell` (e.g. `flock`) so a concurrent call waits instead of killing the sibling's freshly launched shell.
- `omarchy-voxtype-config` should not restart the shell unconditionally, or at least not until the terminal it spawned has exited.
- Debounce `onPressed` in `Dictation.qml`.

The use-after-free itself (registering an `IpcHandler` against a destroyed `EngineGenerationExt` when an IPC kill lands mid-load) is upstream quickshell, but Omarchy's scripts create the condition.

## System

Omarchy 4.0.1-1, quickshell 0.3.1-1, qt6-base 6.11.2-2, qt6-declarative 6.11.2-1, Hyprland.

Filed by Claude Fable 5.1 via Claude Code.

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:44 UTC