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

`omarchy debug` and four other commands are unreachable inside the Hyprland session: envs.lua prepends an incomplete bin dir

Reported by kevinchiha · filed Aug 15, 2026 · open at source

Decided: Out of scope — decided by agents · verified 4 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 debug` and four other commands are unreachable inside the Hyprland session: envs.lua prepends an incomplete bin dirrevision 1 · captured 2026-09-28 21:29 UTC via poll

What happened

Inside a Hyprland session, omarchy debug fails with "Unknown Omarchy command",
along with four other commands. Outside the session (a plain login shell, e.g.
over SSH or a TTY) the very same commands work.

# in a terminal inside the Hyprland session
$ omarchy debug --no-sudo --print
Unknown Omarchy command: omarchy debug --no-sudo --print
Run 'omarchy commands --all' to discover available commands.

# same machine, clean login shell
$ env -i HOME=$HOME bash -lc 'omarchy debug --no-sudo --print' | head -3
Date: Sat Aug 15 04:43:49 PM EEST 2026
Hostname: omarchyos
Omarchy Package: omarchy 4.0.0-1

They are also missing from omarchy commands --all inside the session.

Root cause

bin/omarchy resolves the directory it scans for commands from its own location:

OMARCHY_BIN_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)

so whichever copy of omarchy wins on PATH decides which commands exist.

default/bash/env-bootstrap is careful about this and deliberately does not
prepend $OMARCHY_PATH/bin on a production install:

# Only prepend in dev-link mode. On a production install, the binaries are
# already on PATH as /usr/bin/omarchy-* via the omarchy package — prepending
# /usr/share/omarchy/bin would just be noise.
if [ "$OMARCHY_PATH" != /usr/share/omarchy ]; then
  ...prepend...
fi

But default/hypr/envs.lua prepends it unconditionally, for the whole graphical
session:

local bin_dir = paths.omarchy_path .. "/bin"
local kept = {}
for entry in (os.getenv("PATH") or "/usr/local/bin:/usr/bin"):gmatch("[^:]+") do
  if entry ~= bin_dir then table.insert(kept, entry) end
end
table.insert(kept, 1, bin_dir)
hl.env("PATH", table.concat(kept, ":"))

default/hypr/autostart.lua then pushes that into the systemd user manager:

hl.exec_cmd("systemctl --user import-environment $(env | cut -d'=' -f 1)")

so every terminal and every app started from the session inherits it:

$ systemctl --user show-environment | grep ^PATH=
PATH=/usr/share/omarchy/bin:/home/…/.local/share/mise/shims:…:/usr/bin:…

Why the prepend is not merely "noise"

The two directories are not equivalent. /usr/bin has the complete set; five
binaries shipped by the `omarchy-settings` package never land in
/usr/share/omarchy/bin:

$ comm -23 <(cd /usr/bin && ls omarchy-* | sort) \
           <(cd /usr/share/omarchy/bin && ls omarchy-* | sort)
omarchy-debug
omarchy-debug-idle
omarchy-nvim-refresh
omarchy-nvim-setup
omarchy-upload-log

$ ls /usr/bin/omarchy-* | wc -l               # 426
$ ls /usr/share/omarchy/bin/omarchy-* | wc -l # 421

So prepending shadows a complete command directory with an incomplete one, and
those five routes disappear for the entire graphical session.

The two copies of the dispatcher are byte-identical, both owned by omarchy
4.0.0-1, which confirms the only variable is which directory it scans:

$ cmp /usr/bin/omarchy /usr/share/omarchy/bin/omarchy && echo identical
identical
$ /usr/bin/omarchy debug --no-sudo --print   # works
$ /usr/bin/omarchy theme current             # works

Affected routes

RouteBinaryPackage
omarchy debugomarchy-debugomarchy-settings
omarchy debug idleomarchy-debug-idleomarchy-settings
omarchy nvim refreshomarchy-nvim-refreshomarchy-settings
omarchy nvim setupomarchy-nvim-setupomarchy-settings
omarchy upload logomarchy-upload-logomarchy-settings

omarchy-debug itself declares the route it cannot be reached by:

$ head -6 /usr/bin/omarchy-debug
#!/bin/bash

# omarchy:summary=Print debugging information
# omarchy:args=[--no-sudo] [--print]
# omarchy:examples=omarchy debug --print --no-sudo
# omarchy:requires-sudo=true

Why this one stings

omarchy debug --no-sudo --print is what Omarchy's own shipped agent skill tells
users and coding agents to run. From
default/agents/skills/omarchy/SKILL.md:

IMPORTANT: Always run omarchy debug with --no-sudo --print flags to avoid interactive sudo prompts that will hang the terminal.

and from default/agents/skills/omarchy/contributing.md, as step one of filing a
bug report:

``bash # Generate the diagnostic log (also written to /tmp/omarchy-debug.log) omarchy debug --no-sudo --print ``

So the documented way to collect diagnostics fails in the environment users
actually run it in, and omarchy upload log — the command that shares the
resulting log — is unreachable for the same reason.

Steps to reproduce

In a terminal inside a Hyprland session on a production (non-dev-link) install:

echo "$PATH" | tr ':' '\n' | head -1   # /usr/share/omarchy/bin
omarchy debug                          # Unknown Omarchy command
omarchy upload log                     # Unknown Omarchy command
omarchy commands --all | grep -c debug # 0

Suggested fix

Make envs.lua follow the same rule env-bootstrap already states — prepend
$OMARCHY_PATH/bin only when OMARCHY_PATH is not /usr/share/omarchy:

if paths.omarchy_path ~= "/usr/share/omarchy" then
  -- prepend as today
end

Alternatively, ship the five omarchy-settings binaries into
/usr/share/omarchy/bin as well so the two directories stay interchangeable.

Workaround

omarchy-debug --no-sudo --print           # call the binary
/usr/bin/omarchy debug --no-sudo --print  # or the /usr/bin dispatcher

System details

  • Omarchy: 4.0.0-1 (omarchy 4.0.0-1, omarchy-settings 4.0.0-1)
  • CPU: 13th Gen Intel Core i9-13900KF
  • GPU: AMD Navi 31 [Radeon RX 7900 XTX]
  • Kernel: 7.1.8-1-cachyos
  • Upgraded in place from Omarchy 3 with omarchy-upgrade-to-quattro

/etc/omarchy.conf is absent and OMARCHY_PATH is /usr/share/omarchy, i.e.
this is a normal production install, not dev-link. No debug log is attached
because the fault is in command routing and is reproducible from the file lists
and $PATH above.

View raw text
## What happened

Inside a Hyprland session, `omarchy debug` fails with "Unknown Omarchy command",
along with four other commands. Outside the session (a plain login shell, e.g.
over SSH or a TTY) the very same commands work.

```
# in a terminal inside the Hyprland session
$ omarchy debug --no-sudo --print
Unknown Omarchy command: omarchy debug --no-sudo --print
Run 'omarchy commands --all' to discover available commands.

# same machine, clean login shell
$ env -i HOME=$HOME bash -lc 'omarchy debug --no-sudo --print' | head -3
Date: Sat Aug 15 04:43:49 PM EEST 2026
Hostname: omarchyos
Omarchy Package: omarchy 4.0.0-1
```

They are also missing from `omarchy commands --all` inside the session.

## Root cause

`bin/omarchy` resolves the directory it scans for commands from its own location:

```bash
OMARCHY_BIN_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
```

so whichever copy of `omarchy` wins on `PATH` decides which commands exist.

`default/bash/env-bootstrap` is careful about this and deliberately does **not**
prepend `$OMARCHY_PATH/bin` on a production install:

```bash
# Only prepend in dev-link mode. On a production install, the binaries are
# already on PATH as /usr/bin/omarchy-* via the omarchy package — prepending
# /usr/share/omarchy/bin would just be noise.
if [ "$OMARCHY_PATH" != /usr/share/omarchy ]; then
  ...prepend...
fi
```

But `default/hypr/envs.lua` prepends it unconditionally, for the whole graphical
session:

```lua
local bin_dir = paths.omarchy_path .. "/bin"
local kept = {}
for entry in (os.getenv("PATH") or "/usr/local/bin:/usr/bin"):gmatch("[^:]+") do
  if entry ~= bin_dir then table.insert(kept, entry) end
end
table.insert(kept, 1, bin_dir)
hl.env("PATH", table.concat(kept, ":"))
```

`default/hypr/autostart.lua` then pushes that into the systemd user manager:

```lua
hl.exec_cmd("systemctl --user import-environment $(env | cut -d'=' -f 1)")
```

so every terminal and every app started from the session inherits it:

```
$ systemctl --user show-environment | grep ^PATH=
PATH=/usr/share/omarchy/bin:/home/…/.local/share/mise/shims:…:/usr/bin:…
```

## Why the prepend is not merely "noise"

The two directories are not equivalent. `/usr/bin` has the complete set; five
binaries shipped by the **`omarchy-settings`** package never land in
`/usr/share/omarchy/bin`:

```
$ comm -23 <(cd /usr/bin && ls omarchy-* | sort) \
           <(cd /usr/share/omarchy/bin && ls omarchy-* | sort)
omarchy-debug
omarchy-debug-idle
omarchy-nvim-refresh
omarchy-nvim-setup
omarchy-upload-log

$ ls /usr/bin/omarchy-* | wc -l               # 426
$ ls /usr/share/omarchy/bin/omarchy-* | wc -l # 421
```

So prepending shadows a complete command directory with an incomplete one, and
those five routes disappear for the entire graphical session.

The two copies of the dispatcher are byte-identical, both owned by `omarchy`
4.0.0-1, which confirms the only variable is which directory it scans:

```
$ cmp /usr/bin/omarchy /usr/share/omarchy/bin/omarchy && echo identical
identical
$ /usr/bin/omarchy debug --no-sudo --print   # works
$ /usr/bin/omarchy theme current             # works
```

## Affected routes

| Route | Binary | Package |
|---|---|---|
| `omarchy debug` | `omarchy-debug` | omarchy-settings |
| `omarchy debug idle` | `omarchy-debug-idle` | omarchy-settings |
| `omarchy nvim refresh` | `omarchy-nvim-refresh` | omarchy-settings |
| `omarchy nvim setup` | `omarchy-nvim-setup` | omarchy-settings |
| `omarchy upload log` | `omarchy-upload-log` | omarchy-settings |

`omarchy-debug` itself declares the route it cannot be reached by:

```
$ head -6 /usr/bin/omarchy-debug
#!/bin/bash

# omarchy:summary=Print debugging information
# omarchy:args=[--no-sudo] [--print]
# omarchy:examples=omarchy debug --print --no-sudo
# omarchy:requires-sudo=true
```

## Why this one stings

`omarchy debug --no-sudo --print` is what Omarchy's own shipped agent skill tells
users and coding agents to run. From
`default/agents/skills/omarchy/SKILL.md`:

> **IMPORTANT:** Always run `omarchy debug` with `--no-sudo --print` flags to
> avoid interactive sudo prompts that will hang the terminal.

and from `default/agents/skills/omarchy/contributing.md`, as step one of filing a
bug report:

> ```bash
> # Generate the diagnostic log (also written to /tmp/omarchy-debug.log)
> omarchy debug --no-sudo --print
> ```

So the documented way to collect diagnostics fails in the environment users
actually run it in, and `omarchy upload log` — the command that shares the
resulting log — is unreachable for the same reason.

## Steps to reproduce

In a terminal inside a Hyprland session on a production (non-dev-link) install:

```bash
echo "$PATH" | tr ':' '\n' | head -1   # /usr/share/omarchy/bin
omarchy debug                          # Unknown Omarchy command
omarchy upload log                     # Unknown Omarchy command
omarchy commands --all | grep -c debug # 0
```

## Suggested fix

Make `envs.lua` follow the same rule `env-bootstrap` already states — prepend
`$OMARCHY_PATH/bin` only when `OMARCHY_PATH` is not `/usr/share/omarchy`:

```lua
if paths.omarchy_path ~= "/usr/share/omarchy" then
  -- prepend as today
end
```

Alternatively, ship the five `omarchy-settings` binaries into
`/usr/share/omarchy/bin` as well so the two directories stay interchangeable.

## Workaround

```bash
omarchy-debug --no-sudo --print           # call the binary
/usr/bin/omarchy debug --no-sudo --print  # or the /usr/bin dispatcher
```

## System details

- Omarchy: 4.0.0-1 (`omarchy` 4.0.0-1, `omarchy-settings` 4.0.0-1)
- CPU: 13th Gen Intel Core i9-13900KF
- GPU: AMD Navi 31 [Radeon RX 7900 XTX]
- Kernel: 7.1.8-1-cachyos
- Upgraded in place from Omarchy 3 with `omarchy-upgrade-to-quattro`

`/etc/omarchy.conf` is absent and `OMARCHY_PATH` is `/usr/share/omarchy`, i.e.
this is a normal production install, not dev-link. No debug log is attached
because the fault is in command routing and is reproducible from the file lists
and `$PATH` above.

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 04:08 UTC