Skip to content

fix(install): probe /dev/tty by opening it, not bare existence (#16746) - #17024

Merged
teknium1 merged 3 commits into
mainfrom
hermes/hermes-3a4a8dda
Apr 28, 2026
Merged

fix(install): probe /dev/tty by opening it, not bare existence (#16746)#17024
teknium1 merged 3 commits into
mainfrom
hermes/hermes-3a4a8dda

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvages #16750 by @briandevans and widens the fix to the two sibling gates the original PR punted.

Summary

Replace every [ -e /dev/tty ] gate in scripts/install.sh that guards a subsequent < /dev/tty redirect with an open-based probe (: </dev/tty) 2>/dev/null. In Docker builds the device node exists in the mount namespace but opening it fails with ENXIO, so the bare existence test returned true and the redirect crashed the build a few lines later.

Changes

  • scripts/install.sh — three sites, same fix:
  • tests/test_install_sh_setup_wizard_tty_probe.py — parametrized over all three functions so any future regression is caught regardless of which site breaks.

Validation

Before After
Probe on stdin=/dev/null [ -e /dev/tty ] passes → crash on < /dev/tty (: </dev/tty) fails → skip runs
Probe on real tty passes (unchanged) passes (unchanged)
Regression test n/a 6 passed (3 functions × 2 assertions)
bash -n syntax OK OK

Related

Credit

@briandevans wrote the wizard fix and the original regex-based regression test. This PR rebase-merges those commits and adds a widening commit for the two sibling sites plus test parametrization.

briandevans and others added 3 commits April 28, 2026 06:45
In Docker builds the `/dev/tty` device node is present in the mount
namespace, so `[ -e /dev/tty ]` returns true — but opening it fails
with `ENXIO: No such device or address`. Under the old gate the
"no terminal available" skip never triggered, the setup wizard ran,
and the build aborted a few lines later when bash tried `< /dev/tty`:

    /tmp/install.sh: line 1347: /dev/tty: No such device or address

Replace the existence check with `(: </dev/tty) 2>/dev/null`, which
actually attempts to open /dev/tty in a subshell. The probe succeeds
when piped from `curl | bash` on a real terminal (the wizard's intended
use case) and fails cleanly in Docker build / CI contexts so the skip
kicks in before the redirect can crash.

Add a regression test that statically asserts run_setup_wizard does not
gate on the bare existence check and that the open-based probe is in
place.

Fixes #16746.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address the three Copilot inline findings on the regression test:

- Switch _extract_run_setup_wizard() from str.index() with hard-coded
  markers (which raises ValueError if `maybe_start_gateway()` is renamed
  or the marker leaks into a comment) to an anchored regex on the
  function-definition + closing-brace boundaries.
- Match `[ -e /dev/tty ]` with surrounding whitespace, optional quoting,
  and the `test -e /dev/tty` form so the regression guard catches every
  spelling of the existence-only check, not just the exact substring.
- Replace the literal `(: </dev/tty)` substring assertion with a
  higher-level invariant — the gate must be an `if`/`if !` whose test
  redirects stdin from /dev/tty — so equivalent open-based probes
  (`exec 3</dev/tty` + close, brace-grouped variants, etc.) keep the
  test green while the bare existence check stays caught.

Verified guard: both tests still pass on the fix and both fail on
`origin/main` with the documented messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The contributor's PR (#16750) scoped the fix to run_setup_wizard() and
explicitly punted the two sibling sites. Both have the identical
[ -e /dev/tty ] pattern followed by a < /dev/tty redirect and crash in
Docker the same way:

- scripts/install.sh:732 install_system_packages() -- apt sudo prompt
  fallback. sudo ... < /dev/tty dies with the same ENXIO.
- scripts/install.sh:1395 maybe_start_gateway() -- gateway-install gate,
  same function path as the wizard reproducer.

Fix both with the same (: </dev/tty) 2>/dev/null probe, and parametrize
the regression test over all three gated functions so any future
regression is caught regardless of which site breaks.
@teknium1
teknium1 force-pushed the hermes/hermes-3a4a8dda branch from 63acb0a to 0e36873 Compare April 28, 2026 13:45
@teknium1
teknium1 merged commit 3d8be2c into main Apr 28, 2026
7 checks passed
@teknium1
teknium1 deleted the hermes/hermes-3a4a8dda branch April 28, 2026 13:45
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/docker Docker image, Compose, packaging labels Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Installer setup wizard fails in Docker builds: [ -e /dev/tty ] check unreliable

4 participants