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

omarchy update aborts on a migration's omarchy-bar put: ask_to_put retries a starting shell 50x but a busy one 0x, so a 2s IPC timeout kills the whole update after the widget was already placed

Reported by pedrohcmeneses · filed Sep 21, 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

omarchy update aborts on a migration's omarchy-bar put: ask_to_put retries a starting shell 50x but a busy one 0x, so a 2s IPC timeout kills the whole update after the widget was already placedrevision 1 · captured 2026-09-28 21:23 UTC via poll

What happened

omarchy update aborted on migration 1789581661 (Install Elsewhen, the world clock plugin) with:

Running migration (1789581661)
Install Elsewhen, the world clock plugin
...
(1/1) installing elsewhen                                     [------------] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
omarchy-bar: could not put omacom.elsewhen on the bar: omarchy-shell is not responding

Something went wrong during the update!

The migration's work had actually been applied. Checked right after the failure:

  • omacom.elsewhen was already in ~/.config/omarchy/shell.json — the file's mtime was the moment of the failed call, and the widget sat in the bar layout with its default zones.
  • omarchy-shell shell listPlugins listed the plugin as loaded.
  • omarchy-shell shell ping answered ok in ~60 ms.
  • The quickshell PID was unchanged. Nothing had crashed.

The shell served putBarWidget and wrote the config; only the client gave up before the reply arrived. But the migration died, so omarchy-migrate never wrote its marker, and everything after omarchy-migrate in omarchy-update was skipped: omarchy-hook post-update, omarchy-update-aur-pkgs, omarchy-update-mise, omarchy-update-orphan-pkgs, omarchy-update-analyze-logs, omarchy-update-status and omarchy-update-restart. The next migration (1789764927, OWE backgrounds) stayed pending, and the shell was left running the pre-upgrade QML.

Cause

omarchy-shell wraps every call in timeout ${OMARCHY_SHELL_IPC_TIMEOUT:-2s} and maps exit 124/137 to omarchy-shell is not responding (bin/omarchy-shell:58-63).

ask_to_put in bin/omarchy-bar (line 238) is patient about two failure modes and fatal about the third:

for (( attempt = 0; attempt < ${OMARCHY_SHELL_READY_ATTEMPTS:-50}; attempt++ )); do
  if PUT_RESULT=$(omarchy-shell shell putBarWidget "$id" "$placement" 2>&1); then
    SHELL_ANSWERED=1
    [[ $PUT_RESULT == "not ready" ]] || return 0
  elif [[ $PUT_RESULT == *"not ready"* ]]; then     # retried
    SHELL_ANSWERED=1
  elif [[ $PUT_RESULT == *"is not running"* ]]; then # retried
    ...
  else
    fail "could not put $id on the bar: $PUT_RESULT" # line 258 - timeout lands here, no retry
  fi
  sleep 0.1
done

A shell that is starting gets 50 attempts. A shell that is busy gets one, and the migration dies under set -euo pipefail, taking the whole update with it.

What makes it busy is the update itself: omarchy-dev and omarchy-settings-dev are upgraded in the same pacman transaction that the migrations run after, the post-transaction hook reloads, and the migration calls omarchy-shell shell rescanPlugins on the line immediately before the put. The shell is rebuilding every panel, service and bar widget when the put arrives.

Reproduction / measurements

The window is load dependent, which is why this is intermittent. On this machine (31 installed plugins), measured in a quiet shell:

callduration
shell ping60-66 ms
shell rescanPlugins381 ms
shell ping immediately after that rescan121 ms

Well inside 2 s at rest. During the update's own QML reload it is not, and a heavier plugin set narrows the margin further. Re-running the migration afterwards with OMARCHY_SHELL_IPC_TIMEOUT=15s succeeded immediately and printed omacom.elsewhen is on the bar, confirming both the idempotency of the migration and the timeout as the only cause.

Expected

An IPC timeout should be as retriable as not ready — the shell is unreachable for the same reason, it is just busy rather than starting. Any of:

  1. Treat the timeout string in ask_to_put like not ready, so the existing 50-attempt loop covers it. Smallest fix, keeps the fatal branch for genuine errors.
  2. Give omarchy-shell a longer default timeout for calls made from migrations, or let omarchy-migrate export one for the migrations it runs.
  3. Have omarchy-migrate not treat a put failure as fatal to the whole update, since the widget placement is cosmetic and the rest of the update is not.

A migration that cannot place a widget on the bar should not strand the update with pending migrations and a stale shell.

Same root pattern elsewhere

This is the third reported call site of the non-retriable 2 s IPC timeout, and the one with the widest blast radius:

  • #11115 — omarchy plugin update: unguarded rescanPlugins + set -e, exits 1 after a successful update.
  • #9304 — omarchy plugin add --enable: one-shot enablePlugin times out while the shell rebuilds; plugin installed but disabled.

Both of those leave the user with a wrong exit code or a half-applied plugin. This one aborts omarchy update. A shared fix at the omarchy-shell level (retry/backoff on timeout, or a documented longer default for scripted callers) would cover all three.

System

  • Omarchy 4.0.0.r2186.gee8ebf6-1 (omarchy-dev / omarchy-settings-dev)
  • Quickshell 0.3.1 (Arch)
  • Intel Core i5-9300H, NVIDIA GeForce GTX 1650 Mobile
  • 31 plugins under ~/.config/omarchy/plugins/
  • Session started by uwsm + SDDM
View raw text
## What happened

`omarchy update` aborted on migration `1789581661` (Install Elsewhen, the world clock plugin) with:

```
Running migration (1789581661)
Install Elsewhen, the world clock plugin
...
(1/1) installing elsewhen                                     [------------] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
omarchy-bar: could not put omacom.elsewhen on the bar: omarchy-shell is not responding

Something went wrong during the update!
```

**The migration's work had actually been applied.** Checked right after the failure:

- `omacom.elsewhen` was already in `~/.config/omarchy/shell.json` — the file's mtime was the moment of the failed call, and the widget sat in the bar layout with its default `zones`.
- `omarchy-shell shell listPlugins` listed the plugin as loaded.
- `omarchy-shell shell ping` answered `ok` in ~60 ms.
- The quickshell PID was unchanged. Nothing had crashed.

The shell served `putBarWidget` and wrote the config; only the client gave up before the reply arrived. But the migration died, so `omarchy-migrate` never wrote its marker, and everything after `omarchy-migrate` in `omarchy-update` was skipped: `omarchy-hook post-update`, `omarchy-update-aur-pkgs`, `omarchy-update-mise`, `omarchy-update-orphan-pkgs`, `omarchy-update-analyze-logs`, `omarchy-update-status` and `omarchy-update-restart`. The next migration (`1789764927`, OWE backgrounds) stayed pending, and the shell was left running the pre-upgrade QML.

## Cause

`omarchy-shell` wraps every call in `timeout ${OMARCHY_SHELL_IPC_TIMEOUT:-2s}` and maps exit 124/137 to `omarchy-shell is not responding` (`bin/omarchy-shell:58-63`).

`ask_to_put` in `bin/omarchy-bar` (line 238) is patient about two failure modes and fatal about the third:

```bash
for (( attempt = 0; attempt < ${OMARCHY_SHELL_READY_ATTEMPTS:-50}; attempt++ )); do
  if PUT_RESULT=$(omarchy-shell shell putBarWidget "$id" "$placement" 2>&1); then
    SHELL_ANSWERED=1
    [[ $PUT_RESULT == "not ready" ]] || return 0
  elif [[ $PUT_RESULT == *"not ready"* ]]; then     # retried
    SHELL_ANSWERED=1
  elif [[ $PUT_RESULT == *"is not running"* ]]; then # retried
    ...
  else
    fail "could not put $id on the bar: $PUT_RESULT" # line 258 - timeout lands here, no retry
  fi
  sleep 0.1
done
```

A shell that is *starting* gets 50 attempts. A shell that is *busy* gets one, and the migration dies under `set -euo pipefail`, taking the whole update with it.

What makes it busy is the update itself: `omarchy-dev` and `omarchy-settings-dev` are upgraded in the same pacman transaction that the migrations run after, the post-transaction hook reloads, and the migration calls `omarchy-shell shell rescanPlugins` on the line immediately before the `put`. The shell is rebuilding every panel, service and bar widget when the `put` arrives.

## Reproduction / measurements

The window is load dependent, which is why this is intermittent. On this machine (31 installed plugins), measured in a quiet shell:

| call | duration |
|---|---|
| `shell ping` | 60-66 ms |
| `shell rescanPlugins` | 381 ms |
| `shell ping` immediately after that rescan | 121 ms |

Well inside 2 s at rest. During the update's own QML reload it is not, and a heavier plugin set narrows the margin further. Re-running the migration afterwards with `OMARCHY_SHELL_IPC_TIMEOUT=15s` succeeded immediately and printed `omacom.elsewhen is on the bar`, confirming both the idempotency of the migration and the timeout as the only cause.

## Expected

An IPC timeout should be as retriable as `not ready` — the shell is unreachable for the same reason, it is just busy rather than starting. Any of:

1. Treat the timeout string in `ask_to_put` like `not ready`, so the existing 50-attempt loop covers it. Smallest fix, keeps the fatal branch for genuine errors.
2. Give `omarchy-shell` a longer default timeout for calls made from migrations, or let `omarchy-migrate` export one for the migrations it runs.
3. Have `omarchy-migrate` not treat a `put` failure as fatal to the whole update, since the widget placement is cosmetic and the rest of the update is not.

A migration that cannot place a widget on the bar should not strand the update with pending migrations and a stale shell.

## Same root pattern elsewhere

This is the third reported call site of the non-retriable 2 s IPC timeout, and the one with the widest blast radius:

- #11115 — `omarchy plugin update`: unguarded `rescanPlugins` + `set -e`, exits 1 after a successful update.
- #9304 — `omarchy plugin add --enable`: one-shot `enablePlugin` times out while the shell rebuilds; plugin installed but disabled.

Both of those leave the user with a wrong exit code or a half-applied plugin. This one aborts `omarchy update`. A shared fix at the `omarchy-shell` level (retry/backoff on timeout, or a documented longer default for scripted callers) would cover all three.

## System

- Omarchy `4.0.0.r2186.gee8ebf6-1` (`omarchy-dev` / `omarchy-settings-dev`)
- Quickshell 0.3.1 (Arch)
- Intel Core i5-9300H, NVIDIA GeForce GTX 1650 Mobile
- 31 plugins under `~/.config/omarchy/plugins/`
- Session started by uwsm + SDDM

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 19:22 UTC