Skip to content

fix: prevent silent abort in piped install when interactive prompts fail (#69) - #72

Merged
teknium1 merged 2 commits into
NousResearch:mainfrom
cutepawss:fix/install-script-silent-abort
Feb 27, 2026
Merged

fix: prevent silent abort in piped install when interactive prompts fail (#69)#72
teknium1 merged 2 commits into
NousResearch:mainfrom
cutepawss:fix/install-script-silent-abort

Conversation

@cutepawss

Copy link
Copy Markdown
Contributor

Fixes #69

Problem

The install script silently aborts when run via curl | bash on systems where sudo requires a password (e.g. fresh Debian 12 without ripgrep).

Root cause: The script uses set -e (line 16) which exits on any non-zero return code. When running via curl | bash, stdin is a pipe — not a terminal. The read -p command at line 471 (sudo package install prompt) hits EOF on the piped stdin and returns exit code 1. Under set -e, this silently kills the entire script before clone_repo, setup_path, etc. ever run.

Result: uv gets installed but hermes is never set up. No error message is shown.

Reproduction

# Simulates the exact failure:
bash -c 'set -e; echo "before read"; read -p "prompt: " -n 1 -r < /dev/null; echo "NEVER REACHED"'
# Output: "before read" then silent exit with code 1

Fix

Detect non-interactive mode at script start using the standard POSIX test [ -t 0 ] (checks if stdin is a terminal). When running in piped mode, skip all interactive prompts and show clear messages telling the user what to run manually.

if [ -t 0 ]; then
    IS_INTERACTIVE=true
else
    IS_INTERACTIVE=false
fi

This is the same approach used by rustup, nvm, and oh-my-zsh install scripts.

Guarded prompts

Location Prompt Non-interactive behavior
install_system_packages sudo password for ripgrep/ffmpeg Shows sudo apt install ... command to run manually
run_setup_wizard interactive hermes setup Skips, shows hermes setup to run after install
maybe_start_gateway WhatsApp QR pairing Skips, shows hermes whatsapp to run later
maybe_start_gateway gateway service install Skips, shows hermes gateway install to run later

The sudo prompt (row 1) is the direct cause of #69. The other three use the same read -p pattern and would fail identically in piped mode, so they are guarded for completeness.

Verification

# Before fix (silent abort):
bash -c 'set -e; read -p "test: " -n 1 -r < /dev/null; echo "OK"'
# Output: (nothing) — exit code 1

# After fix (completes successfully):
bash -c 'set -e; if [ -t 0 ]; then read -p "test: " -n 1 -r; else echo "skipped"; fi; echo "OK"' < /dev/null
# Output: "skipped" then "OK" — exit code 0

Scope

Single file: scripts/install.sh. No changes to Python code or agent behavior. Normal interactive installs (bash install.sh) are completely unaffected — the prompts work exactly as before when stdin is a terminal.

cutepawss and others added 2 commits February 26, 2026 17:45
…ail (NousResearch#69)

Root cause: the install script uses `set -e` (exit on error) and `read -p`
for interactive prompts. When running via `curl | bash`, stdin is a pipe
(not a terminal), so `read -p` hits EOF and returns exit code 1. Under
`set -e`, this silently aborts the entire script before hermes is installed.

Fix: detect non-interactive mode using `[ -t 0 ]` (standard POSIX test for
terminal stdin) and skip all interactive prompts when running in piped mode.
Clear messages are shown instead, telling the user what to run manually.

Changes:
- Add IS_INTERACTIVE flag at script start ([ -t 0 ] check)
- Guard sudo package install prompt (the direct cause of NousResearch#69)
- Guard setup wizard (calls interactive hermes setup)
- Guard WhatsApp pairing and gateway install prompts

All other prompts use the same read -p pattern and would fail the same way
in piped mode, so they are all guarded for completeness.

Closes NousResearch#69
@teknium1
teknium1 merged commit 9eabdb6 into NousResearch:main Feb 27, 2026
angelburgosrosado pushed a commit to angelburgosrosado/hermes-agent that referenced this pull request Apr 27, 2026
…silent-abort

fix: prevent silent abort in piped install when interactive prompts fail (NousResearch#69)
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…silent-abort

fix: prevent silent abort in piped install when interactive prompts fail (NousResearch#69)
Meraniya pushed a commit to Meraniya/hermes-agent that referenced this pull request Aug 6, 2026
PR NousResearch#71 made the cron ticker self-heal after a stall, but the restart was
silent — the original 17h stall went unnoticed precisely because nothing
announced it. This surfaces the event: when the supervisor detects a stale
heartbeat and restarts the ticker, it now sends a home-channel alert
(reusing the existing cron home-channel delivery path), gated behind
cron.supervisor_alerts (default on) with a 15-min cooldown to prevent
alert storms on a flapping ticker. The alert send is fully exception-
isolated so it can never delay or block ticker recovery.


Claude-Session: https://claude.ai/code/session_01PQKCc5mDedYAiCNyXnTezh

Co-authored-by: Claude <noreply@anthropic.com>
Meraniya pushed a commit to Meraniya/hermes-agent that referenced this pull request Aug 6, 2026
…, NousResearch#69) and mark arc complete (NousResearch#76)

Session close-out audit found the Outcome section only mentioned PR NousResearch#67.
PR NousResearch#69 explicitly self-describes as "follow-up to NousResearch#67" (unsigned-commit
git fallback) and PR NousResearch#68 (AGENTS.md docs) is also a direct follow-up;
neither was recorded. Also clarifies that NousResearch#71/NousResearch#72 (cron ticker
heartbeat/stall fix) are an unrelated arc shipped the same day, not
part of this project.


Claude-Session: https://claude.ai/code/session_01PQKCc5mDedYAiCNyXnTezh

Co-authored-by: Claude <noreply@anthropic.com>
sijav added a commit to sijav/sijav-agent that referenced this pull request Aug 7, 2026
… guard test (NousResearch#72)

The Factory tab referenced CSS custom properties that are NEVER defined
anywhere in the app, so every one silently resolved to its hardcoded
`var(--x, <literal>)` fallback and stopped following the theme:
  * --ui-border  x8  (0 definitions app-wide)
  * --accent     x3  (0 definitions)
  * --border     x2  (0 definitions)
The fallbacks are dark-theme-tuned literals — `rgba(128,128,128,…)` chrome and
a near-black `#2a2a2a` card border on the model-policy panel — which in LIGHT
mode render as washed-out grey / harsh dark edges. That is the reported symptom
(low-contrast, barely readable model panel).

Remapped to tokens styles.css actually defines, matching each use's weight:
  --ui-border  -> --ui-stroke-secondary / -tertiary / -quaternary
  --accent     -> --ui-accent-secondary (the brand tone; --ui-accent is the
                  midground surface, not a blue accent)
  --border     -> --ui-stroke-secondary

A var() fallback makes this class of bug INVISIBLE — the UI renders, just in
the wrong colour — so it needs a test that resolves references against
definitions. Added theme-tokens.test.ts, which parses every var() the plugin
makes and asserts styles.css defines it, plus a vacuity check so a broken
parser can't make it pass for the wrong reason. It caught 2 tokens beyond the
8 found by hand (--accent, --border) while being written.

Scoped to the Factory plugin because the rest of the app is not yet clean:
--muted-foreground (11 refs), --accent (6), --border (2) and --destructive (2)
are still undefined app-wide, filed separately with the quick-entry <select>
repro (transparent background + near-white inherited option colour).

18 Factory tests pass.
Soju06 added a commit to Soju06/hermes-agent that referenced this pull request Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Install script silently aborts when ripgrep is missing — no error shown, hermes command never installed

2 participants