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-4773GitHub issuePublicReceived

omarchy-hook runs hooks with bash, ignoring shebang and executable bit — non-bash hook silently hung omarchy-update

Reported by lvkz-okcapsule · filed Aug 31, 2026Closed upstream on 2026-09-21 by bjarneo via an automated message, as a duplicate of #8492 (R-1395). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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

omarchy-hook runs hooks with bash, ignoring shebang and executable bit — non-bash hook silently hung omarchy-updaterevision 1 · captured 2026-10-04 12:03 UTC via poll

What happened

omarchy-update hung indefinitely — no output, no error — right after the post-transaction pacman hooks. The stuck process tree:

omarchy-update
└─ omarchy-hook post-update
   └─ bash ~/.config/omarchy/hooks/post-update.d/70-menu-order-check
      └─ import json        ← ImageMagick's `import`, waiting forever for a screenshot click

The hook was a Python script with a #!/usr/bin/env python3 shebang. omarchy-hook runs every hook with bash explicitly, so bash interpreted the Python source: the comment lines were harmless, but import json invoked ImageMagick's import(1), which blocks waiting for the user to click a window. The update sat there silently until the process was killed by hand.

Cause

bin/omarchy-hook invokes hooks as bash "$hook" rather than executing the file:

if [[ -d $HOOK_DIR ]]; then
  for hook in "$HOOK_DIR"/*; do
    [[ -f $hook ]] || continue
    [[ $hook == *.sample ]] && continue
    bash "$hook" "$@" || echo "Hook failed: $hook"
  done
fi

This diverges from the manual (https://omarchy.org/manual/dotfiles/) in two ways:

  1. Shebangs are ignored. The manual's framing ("every executable file in there runs") and omarchy hook install copying the script and marking it executable both suggest a hook is executed as a program, i.e. its shebang is honored. It isn't — everything is fed to bash.
  2. The executable bit isn't checked. The manual says every executable file runs, but the loop runs every non-.sample regular file regardless of permissions.

The failure mode is the nasty part: a non-bash hook doesn't fail cleanly, it gets half-interpreted by bash. Depending on what's installed that can silently hang the whole update (any Python hook + ImageMagick reproduces this).

Suggested fix

Execute hooks directly when they're executable, keeping bash as the fallback:

if [[ -x $hook ]]; then
  "$hook" "$@" || echo "Hook failed: $hook"
else
  bash "$hook" "$@" || echo "Hook failed: $hook"
fi

(Same for the single $HOOK_PATH case.)

If the intent is that hooks are bash-only, a line in the manual saying so — and perhaps a warning when a hook's first line isn't a bash shebang — would also resolve this; the silent hang is the real problem.

Reproduce: printf '#!/usr/bin/env python3\nimport json\n' > ~/.config/omarchy/hooks/post-update.d/99-repro; omarchy-hook post-update (with ImageMagick installed) — hangs.

View raw text
## What happened

`omarchy-update` hung indefinitely — no output, no error — right after the post-transaction pacman hooks. The stuck process tree:

```
omarchy-update
└─ omarchy-hook post-update
   └─ bash ~/.config/omarchy/hooks/post-update.d/70-menu-order-check
      └─ import json        ← ImageMagick's `import`, waiting forever for a screenshot click
```

The hook was a Python script with a `#!/usr/bin/env python3` shebang. `omarchy-hook` runs every hook with `bash` explicitly, so bash interpreted the Python source: the comment lines were harmless, but `import json` invoked ImageMagick's `import(1)`, which blocks waiting for the user to click a window. The update sat there silently until the process was killed by hand.

## Cause

`bin/omarchy-hook` invokes hooks as `bash "$hook"` rather than executing the file:

```bash
if [[ -d $HOOK_DIR ]]; then
  for hook in "$HOOK_DIR"/*; do
    [[ -f $hook ]] || continue
    [[ $hook == *.sample ]] && continue
    bash "$hook" "$@" || echo "Hook failed: $hook"
  done
fi
```

This diverges from the manual (https://omarchy.org/manual/dotfiles/) in two ways:

1. **Shebangs are ignored.** The manual's framing ("every executable file in there runs") and `omarchy hook install` copying the script and marking it executable both suggest a hook is executed as a program, i.e. its shebang is honored. It isn't — everything is fed to bash.
2. **The executable bit isn't checked.** The manual says every *executable* file runs, but the loop runs every non-`.sample` regular file regardless of permissions.

The failure mode is the nasty part: a non-bash hook doesn't fail cleanly, it gets half-interpreted by bash. Depending on what's installed that can silently hang the whole update (any Python hook + ImageMagick reproduces this).

## Suggested fix

Execute hooks directly when they're executable, keeping bash as the fallback:

```bash
if [[ -x $hook ]]; then
  "$hook" "$@" || echo "Hook failed: $hook"
else
  bash "$hook" "$@" || echo "Hook failed: $hook"
fi
```

(Same for the single `$HOOK_PATH` case.)

If the intent is that hooks are bash-only, a line in the manual saying so — and perhaps a warning when a hook's first line isn't a bash shebang — would also resolve this; the silent hang is the real problem.

Reproduce: `printf '#!/usr/bin/env python3\nimport json\n' > ~/.config/omarchy/hooks/post-update.d/99-repro; omarchy-hook post-update` (with ImageMagick installed) — hangs.

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.